This code is Script 4e for Kitchel et al. Biotic homogenization, the exception and not the rule for marine fish communities manuscript.

SESSION INFO TO DO

library(data.table)
library(vegan)
library(sf)
library(concaveman) #polygon around points
library(betapart) #allows us to partition beta diversity
library(geosphere)
library(ggpubr) #stat_regline_equation
library(nlme)
library(mgcv) #to make gam
library(cowplot)
library(lme4)

#Pull Dissimilarity Means
distances_dissimilarities_allyears_15perc_excluded.r <- readRDS(here::here("output", "dissimilarities", "distances_dissimilarities_allyears_15perc_excluded.r.rds"))

#make survey and survey unit factors
distances_dissimilarities_allyears_15perc_excluded.r[,survey:=factor(survey)][,survey_unit:=factor(survey_unit)]

#adjust years
distances_dissimilarities_allyears_15perc_excluded.r[,year_adj := year-min(year)+1]

#add new variable for year in sequence per region
distances_dissimilarities_allyears_15perc_excluded.r[,first_year := min(year),.(survey_unit)]
distances_dissimilarities_allyears_15perc_excluded.r[,last_year := max(year),.(survey_unit)]

#distances_dissimilarities_allyears_15perc_excluded.r[,year_in_seq := year-first_year+1]

distances_dissimilarities_allyears_15perc_excluded.r[,years_sampled := last_year-first_year+1]

###Palette for Plotting Palette for plotting all 42 survey units

survey_unit.list <- levels(factor(distances_dissimilarities_allyears_15perc_excluded.r[,survey_unit]))

palette_42 <- c(
  "#5A5156", #AI
  "#DF00DB", #BITS-1
  "#DB8EDA", #BITS-4
  "#F6222E", #CHL
  "#F8A19F", #DFO-NF
  "#16FF32", #DFO-QCS
  "#325A9B", #EBS
  "#3283FE", #EVHOE
  "#FEAF16", #FR-CGFS
  "#fccb6d", #GMEX-Fall
  "#1C8356", #GMEX-Summer
  "#C4451C", #GOA
  "#85660D", #GRL-DE
  "#B0009F", #GSL-N
  "#BF79B8", #GSL-S
  "#1CBE4F", #ICE-GFS
  "#782AB6", #IE-IGFS
  "#90AD1C", #MEDITS
  "#6B003A", #NAM
  "#A75B00", #NEUS-Fall
  "#E3B072", #NEUS-Spring
  "#02E8B6", #NIGFS-1
  "#97E7D5", #NIGFS-4
  "#B00068", #Nor-BTS-3
  "#00B9E3", #NS-IBTS-1
  "#95E2F4", #NS-IBTS-3
  "#B3CE73", #NZ-CHAT
  "#689500", #NZ-ECSI
  "#364d02",#NZ-SUBA
  "#AAF400", #NZ-WCSI
  "#AA0DFE", #PT-IBTS
  "#7f9eb8", #ROCKALL
  "#FA0087", #S-GEORG
  "#DEA0FD", #SCS-Summer
  "#FCEF88", #SEUS-fall
  "#A59405", #SEUS-spring
  "#FCE100", #SEUS-summer
  "#544563", #SWC-IBTS-1
  "#a37fc7", #SWC-IBTS-4
  "#C075A6", #WCANN
  "#BDCDFF", #ZAF-ATL
  "#003EFF"  #ZAF-IND
)

color_link <- data.table(survey_unit = survey_unit.list,hex = palette_42)

Add names for plotting


name_helper <- data.table(Survey_Name_Season = c("Aleutian Islands",
                                    "Baltic Sea Q1",
                                    "Baltic Sea Q4",
                                    "Chile",
                                    "Newfoundland",
                                    "Queen Charlotte Sound",
                                    "Eastern Bering Sea",
                                    "Bay of Biscay",
                                    "English Channel",
                                    "Gulf of Mexico Summer",
                                    "Gulf of Alaska",
                                    "Greenland",
                                    "N Gulf of St. Lawrence",
                                    "S Gulf of St. Lawrence",
                                    "Iceland",
                                    "Irish Sea",
                                    "Mediterranean",
                                    "Namibia",
                                    "NE US Fall",
                                    "NE US Spring",
                                    "N Ireland Q1",
                                    "N Ireland Q4",
                                    "Barents Sea Norway Q3",
                                    "N Sea Q1",
                                    "N Sea Q3",
                                    "Chatham Rise NZ",
                                    "E Coast S Island NZ",
                                    "W Coast S Island NZ",
                                    "Portugal",
                                    "S Georgia",
                                  "Scotian Shelf Summer",
                                  "SE US Fall",
                                  "SE US Spring",
                                  "SE US Summer",
                                  "W Coast US",
                                  "Atlantic Ocean ZA",
                                  "Indian Ocean ZA",
                                   "Rockall Plateau",
                                  "Scotland Shelf Sea Q1",
                                  "Scotland Shelf Sea Q4",
                                  "Falkland Islands",
                                  "Gulf of Mexico Fall",
                                  "Barents Sea Norway Q1",
                                  "Sub-Arctic NZ",
                                  "Scotian Shelf Spring"),
                          survey_unit = c(
                                  "AI",        
                                  "BITS-1",    
                                  "BITS-4",    
                                  "CHL",       
                                  "DFO-NF",    
                                  "DFO-QCS",   
                                  "EBS",       
                                  "EVHOE",     
                                  "FR-CGFS",   
                                  "GMEX-Summer",
                                  "GOA",       
                                  "GRL-DE",    
                                  "GSL-N",     
                                  "GSL-S",     
                                  "ICE-GFS",   
                                  "IE-IGFS",   
                                  "MEDITS",    
                                  "NAM",       
                                  "NEUS-Fall", 
                                  "NEUS-Spring",
                                  "NIGFS-1",   
                                  "NIGFS-4",   
                                  "Nor-BTS-3", 
                                  "NS-IBTS-1", 
                                  "NS-IBTS-3", 
                                  "NZ-CHAT",   
                                  "NZ-ECSI",   
                                  "NZ-WCSI",   
                                  "PT-IBTS",   
                                  "S-GEORG",   
                                  "SCS-SUMMER",
                                  "SEUS-fall", 
                                  "SEUS-spring",
                                  "SEUS-summer",
                                  "WCANN",     
                                  "ZAF-ATL",   
                                  "ZAF-IND",
                                  "ROCKALL",
                                  "SWC-IBTS-1",
                                  "SWC-IBTS-4",
                                  "FALK",
                                  "GMEX-Fall",
                                  "Nor-BTS-1",
                                  "NZ-SUBA",
                                  "SCS-SPRING"
                          ))


color_link <- name_helper[color_link, on = "survey_unit"]

Total versus balanced BC plot

ggplot(distances_dissimilarities_allyears_15perc_excluded.r) +
  geom_point(aes(bray_curtis_dissimilarity_total_mean, bray_curtis_dissimilarity_balanced_mean)) +
  geom_abline(slope = 1, intercept = 0) +
  geom_smooth(aes(bray_curtis_dissimilarity_total_mean, bray_curtis_dissimilarity_balanced_mean)) +
  theme_classic() +
  labs(x = "Total BC dissimilarity",  y = "Balanced changes in abundance/biomass")

ggplot(distances_dissimilarities_allyears_15perc_excluded.r) +
  geom_point(aes(bray_curtis_dissimilarity_total_mean, bray_curtis_dissimilarity_gradient_mean)) +
  geom_abline(slope = 1, intercpet = 0) +
  geom_smooth(aes(bray_curtis_dissimilarity_total_mean, bray_curtis_dissimilarity_gradient_mean)) +
  theme_classic() +
  labs(x = "Total BC dissimilarity",  y = "Abundance/biomass gradient")
  

##Make GAMs

Bray Curtis

bray_curtis_total_gam_15perc_excl <- gam(bray_curtis_dissimilarity_total_mean ~ year + s(survey_unit, year, bs = "fs", m = 1),#random smooth
                                         data = distances_dissimilarities_allyears_15perc_excluded.r)

##Make LMERS

Bray These all converged

#running with lme instead of lmer gave same results, but allowed for calculation of p-value
bray_curtis_total_lme_15perc_excl <- lme(bray_curtis_dissimilarity_total_mean ~ year_adj, random = (~1 + year_adj|survey_unit),data = distances_dissimilarities_allyears_15perc_excluded.r)

#but also run with lmer for confint
bray_curtis_total_lmer_15perc_excl <- lmer(bray_curtis_dissimilarity_total_mean ~ year_adj + (1 + year_adj|survey_unit),data = distances_dissimilarities_allyears_15perc_excluded.r)

summary(bray_curtis_total_lme_15perc_excl)
anova(bray_curtis_total_lme_15perc_excl)

bray_curtis_total_coefs_15perc_excl  <- data.table(coef(bray_curtis_total_lme_15perc_excl))
bray_curtis_total_coefs_15perc_excl [,survey_unit := rownames(coef(bray_curtis_total_lme_15perc_excl))][,Year := round(year_adj,5)][,Intercept := round(`(Intercept)`,2)]
#View(bray_curtis_total_coefs_15perc_excl )

bray_curtis_total_coefs_15perc_excl  <- bray_curtis_total_coefs_15perc_excl [color_link, on = "survey_unit"]

bray_curtis_total_coefs_15perc_excl.exp <- bray_curtis_total_coefs_15perc_excl [,.(Survey_Name_Season, Intercept, Year)]

#export this table
fwrite(bray_curtis_total_coefs_15perc_excl.exp, file = here::here("output","bray_curtis_total_coefs_15perc_excl.exp.csv"))

Get LMER model as predictions


# need to sort out year in seq versus overall year models
#new data for lmer
lmer_year <- seq(min(distances_dissimilarities_allyears_15perc_excluded.r[,year]), max(distances_dissimilarities_allyears_15perc_excluded.r[,year]), by = 0.1)

lmer_year_adj <- seq(min(distances_dissimilarities_allyears_15perc_excluded.r[,year_adj]), max(distances_dissimilarities_allyears_15perc_excluded.r[,year_adj]), by = 0.1)

#predict average lmer
lmer_bray_total_predictions <- data.table(year = lmer_year, year_adj = lmer_year_adj)

#confidence intervals
bray_curtis_total_lmer_15perc_excl_confint <- confint(bray_curtis_total_lmer_15perc_excl)

#populate data table of lmer predictions
lmer_bray_total_predictions[,bray_curtis_lmer_preds := fixef(bray_curtis_total_lmer_15perc_excl)[[1]] + fixef(bray_curtis_total_lmer_15perc_excl)[[2]] * year_adj][,bray_curtis_lmer_preds_lowerCI := bray_curtis_total_lmer_15perc_excl_confint[5] + bray_curtis_total_lmer_15perc_excl_confint[6] * year_adj][,bray_curtis_lmer_preds_upperCI := bray_curtis_total_lmer_15perc_excl_confint[11] + bray_curtis_total_lmer_15perc_excl_confint[12] * year_adj]

###Move forward with Bray Curtis total for only 85% most abundant species in each region

Coefficients for LMER by survey_unit

#unique survey unit year combos
survey_unit_sampling_years <- unique(distances_dissimilarities_allyears_15perc_excluded.r[,.(survey_unit, year_adj, year, years_sampled)])

# see group coefficients
model_coefs_reduced <- data.table(transform(as.data.frame(ranef(bray_curtis_total_lmer_15perc_excl)), lwr = condval - 1.96*condsd, upr = condval + 1.96*condsd))
#https://stackoverflow.com/questions/69805532/extract-the-confidence-intervals-of-lmer-random-effects-plotted-with-dotplotra


#ONLY SLOPES
model_coefs_reduced <- model_coefs_reduced[term == "year_adj",]

model_coefs_reduced[,survey_unit := grp][,year_adj := condval]

#merge with duration of survey
model_coefs_reduced_length <- model_coefs_reduced[survey_unit_sampling_years, on = "survey_unit"]


model_coefs_reduced_length[,years_sampled := as.numeric(years_sampled)][,Directional_Change := ifelse(year_adj > 0, "Differentiation","Homogenization")]

#does it cross zero?
model_coefs_reduced_length[,significant := ifelse(lwr >0 & upr>0,T,ifelse(lwr<0 & upr<0,T,F))]

#significant directional change
model_coefs_reduced_length[,Directional_Change_sig := ifelse(year_adj > 0 & significant == T, "Differentiation",ifelse(year_adj < 0 & significant == T, "Homogenization", "No trend in\ndissimilarity"))]


#min max distances_dissimilarities
min_bray_reduced <- min(distances_dissimilarities_allyears_15perc_excluded.r[,bray_curtis_dissimilarity_total_mean], na.rm = T)
max_bray_reduced <- max(distances_dissimilarities_allyears_15perc_excluded.r[,bray_curtis_dissimilarity_total_mean], na.rm = T)

model_coefs_reduced_length <- model_coefs_reduced_length[color_link, on = "survey_unit"]

#delete any NAs
model_coefs_reduced_length <- na.omit(model_coefs_reduced_length, cols = "significant")

#order table by coefficient
setorder(model_coefs_reduced_length, year_adj)

BC_total_model_coefs_reduced_length.unique_15perc_excl <- unique(model_coefs_reduced_length[,.(condval,condsd, lwr, upr, survey_unit, year_adj, years_sampled, Directional_Change, hex, Survey_Name_Season, significant, Directional_Change_sig)]) 

#extract color hexes
#year adj coef order
color_year_adj_order <- BC_total_model_coefs_reduced_length.unique_15perc_excl[,hex]

#alphabetical order
BC_total_model_coefs_reduced_length.unique.alpha <- setorder(BC_total_model_coefs_reduced_length.unique_15perc_excl, Survey_Name_Season)
color_alpha_order <- BC_total_model_coefs_reduced_length.unique.alpha[,hex]

#alphabetical order
BC_total_model_coefs_reduced_length.unique.alpha_15perc_excl <- setorder(BC_total_model_coefs_reduced_length.unique_15perc_excl, Survey_Name_Season)

BC_total_model_coefs_reduced_length.unique.alpha_15perc_excl[,trend_color := ifelse(Directional_Change_sig == "Homogenization", "#e7ac5b", ifelse(Directional_Change_sig == "Differentiation","#91c874","#cbbfde"))]

color_alpha_order <- BC_total_model_coefs_reduced_length.unique.alpha_15perc_excl[,hex]
color_alpha_order_bytrend <- BC_total_model_coefs_reduced_length.unique.alpha_15perc_excl[, trend_color]

saveRDS(BC_total_model_coefs_reduced_length.unique_15perc_excl, here::here("output","region_stats","BC_total_model_coefs_reduced_length.unique_15perc_excl.Rds"))

Bar Plot Coefficient LMER

#ALT grey scale
BC_total_Dissimilarity_Coef_errorbar_reduced_greyscale_15perc_excl <- ggplot() +
    geom_errorbar(data = model_coefs_reduced_length, aes(x = reorder(Survey_Name_Season, year_adj) , y = year_adj, label = Survey_Name_Season, ymin = lwr, ymax = upr), fill = "grey", width = 0) + #add confidence intervals
  geom_point(data = model_coefs_reduced_length, aes(x = reorder(Survey_Name_Season, year_adj) , y = year_adj, label = Survey_Name_Season, size = years_sampled, fill = Directional_Change_sig, color = Directional_Change_sig), stat = 'identity', shape = 21) +
  scale_fill_manual(values = c("white","black","grey"), name = "Dissimilarity trend", guide="none") +
  scale_color_manual(values = c("black","black","grey"), name = "Dissimilarity trend", guide="none") +
  scale_size_binned(range = c(1,8), name = "Survey period length") +
  geom_hline(yintercept = 0) +
  scale_y_continuous(breaks = seq(-0.005, 0.0075, by = 0.0025), labels = c("-0.005","","0", "", "0.005",  "")) +
  xlab("Survey unit") +
  ylab("β-diversity trend") + #total BC dissimilarity trend
  coord_flip() +
  theme_classic() +
  theme(axis.text.y = element_text(face = "bold"), axis.title.y = element_blank(), axis.text.x = element_text(size = 15), axis.title.x = element_text(size = 15), legend.position = c(0.25,0.7), legend.direction = "vertical")
Warning: Ignoring unknown parameters: `fill`Warning: Ignoring unknown aesthetics: labelWarning: Ignoring unknown aesthetics: label

lternatively, we color this plot by trend experienced

#"#73BA4D","#E0962C","#cbbfde"

BC_total_Dissimilarity_Coef_errorbar_reduced_colorbytrend_15perc_exclu <- ggplot() +
    geom_errorbar(data = model_coefs_reduced_length, aes(x = reorder(Survey_Name_Season, year_adj) , y = year_adj, label = Survey_Name_Season, ymin = lwr, ymax = upr), fill = "grey", width = 0) + #add confidence intervals
  geom_point(data = model_coefs_reduced_length, aes(x = reorder(Survey_Name_Season, year_adj) , y = year_adj, label = Survey_Name_Season, size = years_sampled, color = Directional_Change_sig), stat = 'identity') +
  scale_color_manual(values = c("#73BA4D","#E0962C","#cbbfde"), name = "Dissimilarity trend", guide="none") +
  scale_size_binned(range = c(1,8), name = "Survey period length\n(years)") +
  geom_hline(yintercept = 0) +
  scale_y_continuous(breaks = seq(-0.005, 0.0075, by = 0.0025), labels = c("-0.005","","0", "", "0.005",  "")) +
  xlab("Survey unit") +
  ylab("β-diversity trend") + #total BC dissimilarity trend
  coord_flip() +
  theme_classic() +
  theme(axis.text.y = element_text(face = "bold"), axis.title.y = element_blank(), axis.text.x = element_text(size = 15), axis.title.x = element_text(size = 15), legend.position = c(0.3,0.8), legend.direction = "vertical", legend.text = element_text(size = 15), legend.title = element_text(size = 16))
Warning: Ignoring unknown parameters: `fill`Warning: Ignoring unknown aesthetics: labelWarning: Ignoring unknown aesthetics: label
directional_change_legend_plot_colorbytrend_15perc_exclu <- BC_total_Dissimilarity_Coef_errorbar_reduced_colorbytrend_15perc_exclu + 
  theme(legend.position = "right", legend.background = element_rect(fill= "transparent"), 
         legend.text = element_text(size = 15), legend.title = element_text(size = 16)) +
  guides(colour = guide_legend(override.aes = list(size=6)), size = "none")

Wavy Line Plot for GAMs

Generate predicted values


#add colors and names to full dissimilarity data table
distances_dissimilarities_allyears_15perc_excluded.r <- distances_dissimilarities_allyears_15perc_excluded.r[color_link, on = "survey_unit"]

#generate new data to smooth lines (need year and season survey combinations)
year_survey_unit_expand.dt <- data.table(survey_unit = as.character(NULL), year = as.numeric(NULL), year_adj = as.numeric(NULL ))

for (i in 1:length(survey_unit.list)) {
  #generate year vectors
  survey_unit_years <- unique(distances_dissimilarities_allyears_15perc_excluded.r[survey_unit == survey_unit.list[i],.(survey_unit, year, year_adj)])
  
  years <- seq(min(survey_unit_years[,year]), max(survey_unit_years[,year]), by = 0.1)
  
  year_adjust <- seq(min(survey_unit_years[,year_adj]), max(survey_unit_years[,year_adj]), by = 0.1)
  
  year_survey_unit_expand.dt_addition <- data.table(survey_unit = survey_unit.list[i], year = years, year_adj = year_adjust)
  
  year_survey_unit_expand.dt <- rbind(year_survey_unit_expand.dt, year_survey_unit_expand.dt_addition)
}

#add colors and names to full year and survey unit combination table
year_survey_unit_expand.dt <- year_survey_unit_expand.dt[color_link, on = "survey_unit"]

Alternative, color by trend


points_wavylines_bray_total_year_reduced_gam_colorbytrend_15perc_excl <- ggplot() +
  geom_ribbon(data = lmer_bray_total_predictions, aes(x = year, ymin = bray_curtis_lmer_preds_lowerCI, ymax = bray_curtis_lmer_preds_upperCI), fill = "grey", alpha = 0.3) +
  geom_point(data = na.omit(distances_dissimilarities_allyears_15perc_excluded.r, cols = "year_adj"),
             aes(x = year,
                 y = bray_curtis_dissimilarity_total_mean,
                 fill = Survey_Name_Season), alpha = 0.4, size = 1, shape = 21, color = "white") +
    geom_line(data = na.omit(year_survey_unit_expand.dt, cols = "year_adj"),
             aes(x = year,
                 y = bray_glm_mod_fit,
                 color = Survey_Name_Season), alpha = 0.6) +
  geom_ribbon(data = na.omit(year_survey_unit_expand.dt, cols = "year_adj"), aes(x = year, ymin=bray_glm_mod_fit-bray_glm_mod_fit_SE, ymax=bray_glm_mod_fit+bray_glm_mod_fit_SE, fill =  Survey_Name_Season), alpha=0.1) + #add standard error
  geom_line(data = lmer_bray_total_predictions, aes(x = year, y = bray_curtis_lmer_preds), color = "black") +
    scale_color_manual(values =  color_alpha_order_bytrend, name = "Survey Unit") +
  scale_fill_manual(values =  color_alpha_order_bytrend, guide = "none") +
  theme_classic() +
  lims(x = c(min(distances_dissimilarities_allyears_15perc_excluded.r[,year]),max(distances_dissimilarities_allyears_15perc_excluded.r[,year]))) +
  xlab("Year") +
ylab("β-diversity") +
  theme(legend.position = "null", axis.text = element_text(size = 15), axis.title = element_text(size = 15))

points_wavylines_bray_total_year_reduced_gam_colorbytrend_15perc_excl
Error in `geom_line()`:
! Problem while computing aesthetics.
ℹ Error occurred in the 3rd layer.
Caused by error in `FUN()`:
! object 'bray_glm_mod_fit' not found
Backtrace:
  1. base (local) `<fn>`(x)
  2. ggplot2:::print.ggplot(x)
  4. ggplot2:::ggplot_build.ggplot(x)
  5. ggplot2:::by_layer(...)
 12. ggplot2 (local) f(l = layers[[i]], d = data[[i]])
 13. l$compute_aesthetics(d, plot)
 14. ggplot2 (local) compute_aesthetics(..., self = self)
 15. base::lapply(aesthetics, eval_tidy, data = data, env = env)
 16. rlang (local) FUN(X[[i]], ...)

Get model as predictions

#for plotting, get model as predictions
bray_curtis_total_gam_15perc_excl_predictions <- predict(bray_curtis_total_gam_15perc_excl, se.fit = TRUE, newdata = year_survey_unit_expand.dt)

#merge into table
year_survey_unit_expand.dt[,bray_glm_mod_fit := bray_curtis_total_gam_15perc_excl_predictions$fit][,bray_glm_mod_fit_SE := bray_curtis_total_gam_15perc_excl_predictions$se.fit]

Produce Plot of GAM and mean LMER line

points_wavylines_bray_total_year_reduced_gam_nolmer_15perc_excl
points_wavylines_bray_total_year_reduced_gam_nolmer_15perc_excl

ggsave(points_wavylines_bray_total_year_reduced_gam_nolmer_15perc_excl, path = here::here("figures"), filename ="points_wavylines_bray_total_year_reduced_gam_nolmer_15perc_excl.jpg", height = 5, width = 5, unit = "in")

points_wavylines_bray_total_year_reduced_gam_15perc_excl <- ggplot() +
  geom_ribbon(data = lmer_bray_total_predictions, aes(x = year, ymin = bray_curtis_lmer_preds_lowerCI, ymax = bray_curtis_lmer_preds_upperCI), fill = "grey", alpha = 0.3) +
  geom_point(data = na.omit(distances_dissimilarities_allyears_15perc_excluded.r, cols = "year_adj"),
             aes(x = year,
                 y = bray_curtis_dissimilarity_total_mean,
                 fill = Survey_Name_Season), alpha = 0.4, size = 1, shape = 21, color = "white") +
    geom_line(data = na.omit(year_survey_unit_expand.dt, cols = "year_adj"),
             aes(x = year,
                 y = bray_glm_mod_fit,
                 color = Survey_Name_Season), alpha = 0.6) +
  geom_ribbon(data = na.omit(year_survey_unit_expand.dt, cols = "year_adj"), aes(x = year, ymin=bray_glm_mod_fit-bray_glm_mod_fit_SE, ymax=bray_glm_mod_fit+bray_glm_mod_fit_SE, fill =  Survey_Name_Season), alpha=0.1) + #add standard error
  geom_line(data = lmer_bray_total_predictions, aes(x = year, y = bray_curtis_lmer_preds), color = "black") +
    scale_color_manual(values =  color_alpha_order, name = "Survey Unit") +
  scale_fill_manual(values =  color_alpha_order, guide = "none") +
  theme_classic() +
  lims(x = c(min(distances_dissimilarities_allyears_15perc_excluded.r[,year]),max(distances_dissimilarities_allyears_15perc_excluded.r[,year]))) +
  xlab("Year") +
ylab("β-diversity") +
  theme(legend.position = "null", axis.text = element_text(size = 15), axis.title = element_text(size = 15))
points_wavylines_bray_total_year_reduced_gam_15perc_excl <- ggplot() +
  geom_ribbon(data = lmer_bray_total_predictions, aes(x = year, ymin = bray_curtis_lmer_preds_lowerCI, ymax = bray_curtis_lmer_preds_upperCI), fill = "grey", alpha = 0.3) +
  geom_point(data = na.omit(distances_dissimilarities_allyears_15perc_excluded.r, cols = "year_adj"),
             aes(x = year,
                 y = bray_curtis_dissimilarity_total_mean,
                 fill = Survey_Name_Season), alpha = 0.4, size = 1, shape = 21, color = "white") +
    geom_line(data = na.omit(year_survey_unit_expand.dt, cols = "year_adj"),
             aes(x = year,
                 y = bray_glm_mod_fit,
                 color = Survey_Name_Season), alpha = 0.6) +
  geom_ribbon(data = na.omit(year_survey_unit_expand.dt, cols = "year_adj"), aes(x = year, ymin=bray_glm_mod_fit-bray_glm_mod_fit_SE, ymax=bray_glm_mod_fit+bray_glm_mod_fit_SE, fill =  Survey_Name_Season), alpha=0.1) + #add standard error
  geom_line(data = lmer_bray_total_predictions, aes(x = year, y = bray_curtis_lmer_preds), color = "black") +
    scale_color_manual(values =  color_alpha_order, name = "Survey Unit") +
  scale_fill_manual(values =  color_alpha_order, guide = "none") +
  theme_classic() +
  lims(x = c(min(distances_dissimilarities_allyears_15perc_excluded.r[,year]),max(distances_dissimilarities_allyears_15perc_excluded.r[,year]))) +
  xlab("Year") +
ylab("β-diversity") +
  theme(legend.position = "null", axis.text = element_text(size = 15), axis.title = element_text(size = 15))
points_wavylines_bray_total_year_reduced_gam_15perc_excl
ggsave(points_wavylines_bray_total_year_reduced_gam_15perc_excl, path = here::here("figures"), filename ="points_wavylines_bray_total_year_reduced_gam_15perc_excl.jpg", height = 6, width = 6, unit = "in")

#ALT
#plot all, but same color scheme (grey)
points_wavylines_bray_total_year_reduced_gam_greyscale_15perc_excl <- ggplot() +
  geom_ribbon(data = lmer_bray_total_predictions, aes(x = year, ymin = bray_curtis_lmer_preds_lowerCI, ymax = bray_curtis_lmer_preds_upperCI), fill = "grey", alpha = 0.3) +
  geom_point(data = distances_dissimilarities_allyears_15perc_excluded.r,
             aes(x = year,
                 y = bray_curtis_dissimilarity_total_mean,
                 fill = Survey_Name_Season), alpha = 0.4, size = 1, shape = 21, color = "white") +
    geom_line(data = year_survey_unit_expand.dt,
             aes(x = year,
                 y = bray_glm_mod_fit,
                 color = Survey_Name_Season), alpha = 0.6) +
  geom_ribbon(data = year_survey_unit_expand.dt, aes(x = year, ymin=bray_glm_mod_fit-bray_glm_mod_fit_SE, ymax=bray_glm_mod_fit+bray_glm_mod_fit_SE, fill =  Survey_Name_Season), alpha=0.1) + #add standard error
  geom_line(data = lmer_bray_total_predictions, aes(x = year, y = bray_curtis_lmer_preds), color = "black") +
    scale_color_manual(values =  rep("black", times = length(unique(distances_dissimilarities_allyears_15perc_excluded.r$Survey_Name_Season))), name = "Survey Unit") +
  scale_fill_manual(values =  rep("black", times = length(unique(distances_dissimilarities_allyears_15perc_excluded.r$Survey_Name_Season))), guide = "none") +
  theme_classic() +
  lims(x = c(min(distances_dissimilarities_allyears_15perc_excluded.r[,year]),max(distances_dissimilarities_allyears_15perc_excluded.r[,year]))
       ) +
  xlab("Year") +
ylab("β-diversity") +
  theme(legend.position = "null", axis.text = element_text(size = 15), axis.title = element_text(size = 15))
#ALT
#plot all, but same color scheme (grey)
points_wavylines_bray_total_year_reduced_gam_greyscale_15perc_excl <- ggplot() +
  geom_ribbon(data = lmer_bray_total_predictions, aes(x = year, ymin = bray_curtis_lmer_preds_lowerCI, ymax = bray_curtis_lmer_preds_upperCI), fill = "grey", alpha = 0.3) +
  geom_point(data = distances_dissimilarities_allyears_15perc_excluded.r,
             aes(x = year,
                 y = bray_curtis_dissimilarity_total_mean,
                 fill = Survey_Name_Season), alpha = 0.4, size = 1, shape = 21, color = "white") +
    geom_line(data = year_survey_unit_expand.dt,
             aes(x = year,
                 y = bray_glm_mod_fit,
                 color = Survey_Name_Season), alpha = 0.6) +
  geom_ribbon(data = year_survey_unit_expand.dt, aes(x = year, ymin=bray_glm_mod_fit-bray_glm_mod_fit_SE, ymax=bray_glm_mod_fit+bray_glm_mod_fit_SE, fill =  Survey_Name_Season), alpha=0.1) + #add standard error
  geom_line(data = lmer_bray_total_predictions, aes(x = year, y = bray_curtis_lmer_preds), color = "black") +
    scale_color_manual(values =  rep("black", times = length(unique(distances_dissimilarities_allyears_15perc_excluded.r$Survey_Name_Season))), name = "Survey Unit") +
  scale_fill_manual(values =  rep("black", times = length(unique(distances_dissimilarities_allyears_15perc_excluded.r$Survey_Name_Season))), guide = "none") +
  theme_classic() +
  lims(x = c(min(distances_dissimilarities_allyears_15perc_excluded.r[,year]),max(distances_dissimilarities_allyears_15perc_excluded.r[,year]))
       ) +
  xlab("Year") +
ylab("β-diversity") +
  theme(legend.position = "null", axis.text = element_text(size = 15), axis.title = element_text(size = 15))
points_wavylines_bray_total_year_reduced_gam_greyscale_15perc_excl
ggsave(points_wavylines_bray_total_year_reduced_gam_greyscale_15perc_excl, path = here::here("figures"), filename ="points_wavylines_bray_total_year_reduced_gam_greyscale_15perc_excl.jpg", height = 6, width = 6, unit = "in")

#plot each independently for supplement
#all survey names = 
all_survey_names <- sort(unique(color_link$Survey_Name_Season))
#list of plots
points_wavylines_bray_total_year_reduced_gam_individual_15perc_exclu <- list()
for (i in 1:length(all_survey_names)) {
points_wavylines_bray_total_year_reduced_gam_individual_15perc_exclu[[i]] <- ggplot() +
  geom_point(data = distances_dissimilarities_allyears_15perc_excluded.r[Survey_Name_Season == all_survey_names[i]],
             aes(x = year,
                 y = bray_curtis_dissimilarity_total_mean), alpha = 0.4, color = "black") +
    geom_line(data = year_survey_unit_expand.dt[Survey_Name_Season == all_survey_names[i]],
             aes(x = year,
                 y = bray_glm_mod_fit), alpha = 0.6) +
  geom_ribbon(data = year_survey_unit_expand.dt[Survey_Name_Season == all_survey_names[i]], aes(x = year, ymin=bray_glm_mod_fit-bray_glm_mod_fit_SE, ymax=bray_glm_mod_fit+bray_glm_mod_fit_SE), alpha=0.1) + #add standard error
  theme_classic() +
#  lims(x = c(min(distances_dissimilarities_allyears_15perc_excluded.r[Survey_Name_Season == all_survey_names[i],year]),max(distances_dissimilarities_allyears_15perc_excluded.r[Survey_Name_Season == all_survey_names[i],year])),
#       y = c(0.15,0.9)) +
  xlab("Year") +
ylab("beta-diversity") +
  facet_wrap(~Survey_Name_Season, ncol = 5) +
  theme(legend.position = "null", axis.text = element_text(size = 15), axis.title = element_text(size = 15))

print(points_wavylines_bray_total_year_reduced_gam_individual_15perc_exclu[[i]])

}

saveRDS(points_wavylines_bray_total_year_reduced_gam_individual_15perc_exclu, here::here("figures","points_wavylines_bray_total_year_reduced_gam_individual_15perc_exclu.Rds"))

#print to pdf
library(gridExtra)

ggsave(
   filename = here::here("figures","points_wavylines_bray_total_year_reduced_gam_individual_15perc_exclu.pdf"), 
   plot = marrangeGrob(points_wavylines_bray_total_year_reduced_gam_individual_15perc_exclu, nrow=1, ncol=1), 
   width = 8.5, height = 11
)

#Alternatively, split into 2 and use facet
#first 24
points_wavylines_bray_total_year_reduced_gam_individual_facet_1_24_15perc_exclu <- ggplot() +
  geom_point(data = distances_dissimilarities_allyears_15perc_excluded.r[Survey_Name_Season  %in% all_survey_names[c(1:24)]],
             aes(x = year,
                 y = bray_curtis_dissimilarity_total_mean), alpha = 0.7) +
    geom_line(data = year_survey_unit_expand.dt[Survey_Name_Season   %in% all_survey_names[c(1:24)]],
             aes(x = year,
                 y = bray_glm_mod_fit)) +
  geom_ribbon(data = year_survey_unit_expand.dt[Survey_Name_Season  %in% all_survey_names[c(1:24)]],
aes(x = year, ymin=bray_glm_mod_fit-bray_glm_mod_fit_SE, ymax=bray_glm_mod_fit+bray_glm_mod_fit_SE), alpha=0.5) + #add standard error
  theme_classic() +
  xlab("Year") +
ylab("β-diversity") +
  facet_wrap(~Survey_Name_Season, ncol = 4, scales = "free") +
  theme(axis.text = element_text(size = 8), axis.title = element_text(size = 12))

ggsave(points_wavylines_bray_total_year_reduced_gam_individual_facet_1_24_15perc_exclu, path =  here::here("figures"), filename = "points_wavylines_bray_total_year_reduced_gam_individual_facet_1_24_15perc_exclu.png", height = 11, width = 9)

points_wavylines_bray_total_year_reduced_gam_individual_facet_25_42_15perc_exclu <- ggplot() +
  geom_point(data = distances_dissimilarities_allyears_15perc_excluded.r[Survey_Name_Season  %in% all_survey_names[c(25:42)]],
             aes(x = year,
                 y = bray_curtis_dissimilarity_total_mean), alpha = 0.7) +
    geom_line(data = year_survey_unit_expand.dt[Survey_Name_Season   %in% all_survey_names[c(25:42)]],
             aes(x = year,
                 y = bray_glm_mod_fit)) +
  geom_ribbon(data = year_survey_unit_expand.dt[Survey_Name_Season  %in% all_survey_names[c(25:42)]],
aes(x = year, ymin=bray_glm_mod_fit-bray_glm_mod_fit_SE, ymax=bray_glm_mod_fit+bray_glm_mod_fit_SE), alpha=0.5) + #add standard error
  theme_classic() +
  xlab("Year") +
ylab("β-diversity") +
  facet_wrap(~Survey_Name_Season, ncol = 4, scales = "free") +
  theme(axis.text = element_text(size = 8), axis.title = element_text(size = 12))

ggsave(points_wavylines_bray_total_year_reduced_gam_individual_facet_25_42_15perc_exclu, path =  here::here("figures"), filename = "points_wavylines_bray_total_year_reduced_gam_individual_facet_25_42_15perc_exclu.png", height = 11, width = 9)

NA
NA

Merge BC versus Year plot with GAMS and Region vs. coefficient plot for LMERs

#ALT COLOR BY TREND
BC_total_GAM_LMER_merge_legend_colorbytrend_15perc_exclu <- ggdraw(xlim = c(0, 40.5), ylim = c(0, 21)) +
    draw_plot(points_wavylines_bray_total_year_reduced_gam_colorbytrend_15perc_exclu,
                                         x = 1, y = 1, width = 20, height = 20) +
    draw_plot(BC_total_Dissimilarity_Coef_errorbar_reduced_colorbytrend_15perc_exclu +
        theme(legend.key.size = unit(0.5, 'cm'), #change legend key size
       # legend.title = element_text(size=16), #change legend title font size
       # legend.text = element_text(size=14)
       ), #change legend text font size),
                                         x = 20, y = 1, width = 19, height = 20) +
    draw_plot(get_legend(directional_change_legend_plot_colorbytrend_15perc_exclu + 
      theme(legend.key.size = unit(0.5, 'cm'), #change legend key size
        legend.title = element_text(size=16), #change legend title font size
        legend.text = element_text(size=15))), #change legend text font size)
                                x = 27, y = 8, width = 3, height = 2) +
  geom_text(aes(x = 2, y = 20.7), label = ("a."), size =8, fontface = "bold") +
  geom_text(aes(x =20, y = 20.7), label = ("b."), size =8, fontface = "bold")
Error in as_grob(plot) : 
  object 'points_wavylines_bray_total_year_reduced_gam_colorbytrend_15perc_exclu' not found
LS0tCnRpdGxlOiAiWWVhciBUT1RBTCBEaXNzaW1pbGFyaXR5IE1vZGVscyBidXQgZXhjbHVkaW5nIDE1JSBsZWFzdCBjb21tb24gc3BlY2llcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBjb2RlIGlzIFNjcmlwdCA0ZSAgZm9yIEtpdGNoZWwgZXQgYWwuIEJpb3RpYyBob21vZ2VuaXphdGlvbiwgdGhlIGV4Y2VwdGlvbiBhbmQgbm90IHRoZSBydWxlIGZvciBtYXJpbmUgZmlzaCBjb21tdW5pdGllcyBtYW51c2NyaXB0LgoKLSBUaGlzIHByb2plY3QgaXMgYSBjb2xsYWJvcmF0aXZlIGVmZm9ydCB0byBkZXNjcmliZSBjaGFuZ2VzIGluIHRheG9ub21pYyBjb21wb3NpdGlvbiAgb2YgZmlzaCBjb21tdW5pdGllcyBhcm91bmQgdGhlIHdvcmxkLS1hcyBzYW1wbGVkIGJ5IGJvdHRvbSB0cmF3bCBzdXJ2ZXlzLgoKLSBDb2RlIGJ5IFpvw6sgSi4gS2l0Y2hlbAoKU0VTU0lPTiBJTkZPIFRPIERPCgpgYGB7ciBzZXR1cH0KbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KHZlZ2FuKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KGNvbmNhdmVtYW4pICNwb2x5Z29uIGFyb3VuZCBwb2ludHMKbGlicmFyeShiZXRhcGFydCkgI2FsbG93cyB1cyB0byBwYXJ0aXRpb24gYmV0YSBkaXZlcnNpdHkKbGlicmFyeShnZW9zcGhlcmUpCmxpYnJhcnkoZ2dwdWJyKSAjc3RhdF9yZWdsaW5lX2VxdWF0aW9uCmxpYnJhcnkobmxtZSkKbGlicmFyeShtZ2N2KSAjdG8gbWFrZSBnYW0KbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KGxtZTQpCgojUHVsbCBEaXNzaW1pbGFyaXR5IE1lYW5zCmRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnIgPC0gcmVhZFJEUyhoZXJlOjpoZXJlKCJvdXRwdXQiLCAiZGlzc2ltaWxhcml0aWVzIiwgImRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnIucmRzIikpCgojbWFrZSBzdXJ2ZXkgYW5kIHN1cnZleSB1bml0IGZhY3RvcnMKZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclssc3VydmV5Oj1mYWN0b3Ioc3VydmV5KV1bLHN1cnZleV91bml0Oj1mYWN0b3Ioc3VydmV5X3VuaXQpXQoKI2FkanVzdCB5ZWFycwpkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWyx5ZWFyX2FkaiA6PSB5ZWFyLW1pbih5ZWFyKSsxXQoKI2FkZCBuZXcgdmFyaWFibGUgZm9yIHllYXIgaW4gc2VxdWVuY2UgcGVyIHJlZ2lvbgpkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWyxmaXJzdF95ZWFyIDo9IG1pbih5ZWFyKSwuKHN1cnZleV91bml0KV0KZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclssbGFzdF95ZWFyIDo9IG1heCh5ZWFyKSwuKHN1cnZleV91bml0KV0KCiNkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWyx5ZWFyX2luX3NlcSA6PSB5ZWFyLWZpcnN0X3llYXIrMV0KCmRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnJbLHllYXJzX3NhbXBsZWQgOj0gbGFzdF95ZWFyLWZpcnN0X3llYXIrMV0KCgpgYGAKCiMjI1BhbGV0dGUgZm9yIFBsb3R0aW5nClBhbGV0dGUgZm9yIHBsb3R0aW5nIGFsbCA0MiBzdXJ2ZXkgdW5pdHMKYGBge3IgbGluayBjb2xvcnMgdG8gc3VydmV5IHVuaXRzfQpzdXJ2ZXlfdW5pdC5saXN0IDwtIGxldmVscyhmYWN0b3IoZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclssc3VydmV5X3VuaXRdKSkKCnBhbGV0dGVfNDIgPC0gYygKICAiIzVBNTE1NiIsICNBSQogICIjREYwMERCIiwgI0JJVFMtMQogICIjREI4RURBIiwgI0JJVFMtNAogICIjRjYyMjJFIiwgI0NITAogICIjRjhBMTlGIiwgI0RGTy1ORgogICIjMTZGRjMyIiwgI0RGTy1RQ1MKICAiIzMyNUE5QiIsICNFQlMKICAiIzMyODNGRSIsICNFVkhPRQogICIjRkVBRjE2IiwgI0ZSLUNHRlMKICAiI2ZjY2I2ZCIsICNHTUVYLUZhbGwKICAiIzFDODM1NiIsICNHTUVYLVN1bW1lcgogICIjQzQ0NTFDIiwgI0dPQQogICIjODU2NjBEIiwgI0dSTC1ERQogICIjQjAwMDlGIiwgI0dTTC1OCiAgIiNCRjc5QjgiLCAjR1NMLVMKICAiIzFDQkU0RiIsICNJQ0UtR0ZTCiAgIiM3ODJBQjYiLCAjSUUtSUdGUwogICIjOTBBRDFDIiwgI01FRElUUwogICIjNkIwMDNBIiwgI05BTQogICIjQTc1QjAwIiwgI05FVVMtRmFsbAogICIjRTNCMDcyIiwgI05FVVMtU3ByaW5nCiAgIiMwMkU4QjYiLCAjTklHRlMtMQogICIjOTdFN0Q1IiwgI05JR0ZTLTQKICAiI0IwMDA2OCIsICNOb3ItQlRTLTMKICAiIzAwQjlFMyIsICNOUy1JQlRTLTEKICAiIzk1RTJGNCIsICNOUy1JQlRTLTMKICAiI0IzQ0U3MyIsICNOWi1DSEFUCiAgIiM2ODk1MDAiLCAjTlotRUNTSQogICIjMzY0ZDAyIiwjTlotU1VCQQogICIjQUFGNDAwIiwgI05aLVdDU0kKICAiI0FBMERGRSIsICNQVC1JQlRTCiAgIiM3ZjllYjgiLCAjUk9DS0FMTAogICIjRkEwMDg3IiwgI1MtR0VPUkcKICAiI0RFQTBGRCIsICNTQ1MtU3VtbWVyCiAgIiNGQ0VGODgiLCAjU0VVUy1mYWxsCiAgIiNBNTk0MDUiLCAjU0VVUy1zcHJpbmcKICAiI0ZDRTEwMCIsICNTRVVTLXN1bW1lcgogICIjNTQ0NTYzIiwgI1NXQy1JQlRTLTEKICAiI2EzN2ZjNyIsICNTV0MtSUJUUy00CiAgIiNDMDc1QTYiLCAjV0NBTk4KICAiI0JEQ0RGRiIsICNaQUYtQVRMCiAgIiMwMDNFRkYiICAjWkFGLUlORAopCgpjb2xvcl9saW5rIDwtIGRhdGEudGFibGUoc3VydmV5X3VuaXQgPSBzdXJ2ZXlfdW5pdC5saXN0LGhleCA9IHBhbGV0dGVfNDIpCmBgYAoKQWRkIG5hbWVzIGZvciBwbG90dGluZwpgYGB7ciBhZGQgbmFtZXMgZm9yIHBsb3R0aW5nfQoKbmFtZV9oZWxwZXIgPC0gZGF0YS50YWJsZShTdXJ2ZXlfTmFtZV9TZWFzb24gPSBjKCJBbGV1dGlhbiBJc2xhbmRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhbHRpYyBTZWEgUTEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmFsdGljIFNlYSBRNCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDaGlsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOZXdmb3VuZGxhbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUXVlZW4gQ2hhcmxvdHRlIFNvdW5kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVhc3Rlcm4gQmVyaW5nIFNlYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCYXkgb2YgQmlzY2F5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVuZ2xpc2ggQ2hhbm5lbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHdWxmIG9mIE1leGljbyBTdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR3VsZiBvZiBBbGFza2EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR3JlZW5sYW5kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk4gR3VsZiBvZiBTdC4gTGF3cmVuY2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUyBHdWxmIG9mIFN0LiBMYXdyZW5jZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJY2VsYW5kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklyaXNoIFNlYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNZWRpdGVycmFuZWFuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5hbWliaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkUgVVMgRmFsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJORSBVUyBTcHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTiBJcmVsYW5kIFExIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk4gSXJlbGFuZCBRNCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCYXJlbnRzIFNlYSBOb3J3YXkgUTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTiBTZWEgUTEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTiBTZWEgUTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2hhdGhhbSBSaXNlIE5aIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkUgQ29hc3QgUyBJc2xhbmQgTloiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVyBDb2FzdCBTIElzbGFuZCBOWiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3J0dWdhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTIEdlb3JnaWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjb3RpYW4gU2hlbGYgU3VtbWVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRSBVUyBGYWxsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRSBVUyBTcHJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNFIFVTIFN1bW1lciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVyBDb2FzdCBVUyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXRsYW50aWMgT2NlYW4gWkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkluZGlhbiBPY2VhbiBaQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJvY2thbGwgUGxhdGVhdSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NvdGxhbmQgU2hlbGYgU2VhIFExIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTY290bGFuZCBTaGVsZiBTZWEgUTQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhbGtsYW5kIElzbGFuZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkd1bGYgb2YgTWV4aWNvIEZhbGwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhcmVudHMgU2VhIE5vcndheSBRMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3ViLUFyY3RpYyBOWiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NvdGlhbiBTaGVsZiBTcHJpbmciKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdCA9IGMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUkiLCAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQklUUy0xIiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQklUUy00IiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0hMIiwgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiREZPLU5GIiwgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiREZPLVFDUyIsICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRUJTIiwgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRVZIT0UiLCAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRlItQ0dGUyIsICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR01FWC1TdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdPQSIsICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdSTC1ERSIsICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdTTC1OIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdTTC1TIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklDRS1HRlMiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklFLUlHRlMiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1FRElUUyIsICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5BTSIsICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVMtRmFsbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5FVVMtU3ByaW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOSUdGUy0xIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOSUdGUy00IiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb3ItQlRTLTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOUy1JQlRTLTEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOUy1JQlRTLTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1DSEFUIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1FQ1NJIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1XQ1NJIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQVC1JQlRTIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTLUdFT1JHIiwgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQ1MtU1VNTUVSIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRVVTLWZhbGwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTRVVTLXNwcmluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0VVUy1zdW1tZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldDQU5OIiwgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlpBRi1BVEwiLCAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlpBRi1JTkQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJPQ0tBTEwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNXQy1JQlRTLTEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNXQy1JQlRTLTQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZBTEsiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdNRVgtRmFsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm9yLUJUUy0xIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOWi1TVUJBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQ1MtU1BSSU5HIgogICAgICAgICAgICAgICAgICAgICAgICAgICkpCgoKY29sb3JfbGluayA8LSBuYW1lX2hlbHBlcltjb2xvcl9saW5rLCBvbiA9ICJzdXJ2ZXlfdW5pdCJdCgpgYGAKClRvdGFsIHZlcnN1cyBiYWxhbmNlZCBCQyBwbG90CmBgYHtyfQpnZ3Bsb3QoZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQucikgKwogIGdlb21fcG9pbnQoYWVzKGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfdG90YWxfbWVhbiwgYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9iYWxhbmNlZF9tZWFuKSkgKwogIGdlb21fYWJsaW5lKHNsb3BlID0gMSwgaW50ZXJjZXB0ID0gMCkgKwogIGdlb21fc21vb3RoKGFlcyhicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X3RvdGFsX21lYW4sIGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfYmFsYW5jZWRfbWVhbikpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIGxhYnMoeCA9ICJUb3RhbCBCQyBkaXNzaW1pbGFyaXR5IiwgIHkgPSAiQmFsYW5jZWQgY2hhbmdlcyBpbiBhYnVuZGFuY2UvYmlvbWFzcyIpCgpnZ3Bsb3QoZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQucikgKwogIGdlb21fcG9pbnQoYWVzKGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfdG90YWxfbWVhbiwgYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV9ncmFkaWVudF9tZWFuKSkgKwogIGdlb21fYWJsaW5lKHNsb3BlID0gMSwgaW50ZXJjcGV0ID0gMCkgKwogIGdlb21fc21vb3RoKGFlcyhicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X3RvdGFsX21lYW4sIGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfZ3JhZGllbnRfbWVhbikpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIGxhYnMoeCA9ICJUb3RhbCBCQyBkaXNzaW1pbGFyaXR5IiwgIHkgPSAiQWJ1bmRhbmNlL2Jpb21hc3MgZ3JhZGllbnQiKQogIApgYGAKCgojI01ha2UgR0FNcwoKQnJheSBDdXJ0aXMKYGBge3IgYnJheSBjdXJ0aXMgZ2Ftc30KYnJheV9jdXJ0aXNfdG90YWxfZ2FtXzE1cGVyY19leGNsIDwtIGdhbShicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X3RvdGFsX21lYW4gfiB5ZWFyICsgcyhzdXJ2ZXlfdW5pdCwgeWVhciwgYnMgPSAiZnMiLCBtID0gMSksI3JhbmRvbSBzbW9vdGgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQucikKCgpgYGAKCgojI01ha2UgTE1FUlMKCkJyYXkKKlRoZXNlIGFsbCBjb252ZXJnZWQqCmBgYHtyIGJyYXl9CiNydW5uaW5nIHdpdGggbG1lIGluc3RlYWQgb2YgbG1lciBnYXZlIHNhbWUgcmVzdWx0cywgYnV0IGFsbG93ZWQgZm9yIGNhbGN1bGF0aW9uIG9mIHAtdmFsdWUKYnJheV9jdXJ0aXNfdG90YWxfbG1lXzE1cGVyY19leGNsIDwtIGxtZShicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X3RvdGFsX21lYW4gfiB5ZWFyX2FkaiwgcmFuZG9tID0gKH4xICsgeWVhcl9hZGp8c3VydmV5X3VuaXQpLGRhdGEgPSBkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yKQoKI2J1dCBhbHNvIHJ1biB3aXRoIGxtZXIgZm9yIGNvbmZpbnQKYnJheV9jdXJ0aXNfdG90YWxfbG1lcl8xNXBlcmNfZXhjbCA8LSBsbWVyKGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfdG90YWxfbWVhbiB+IHllYXJfYWRqICsgKDEgKyB5ZWFyX2FkanxzdXJ2ZXlfdW5pdCksZGF0YSA9IGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnIpCgpzdW1tYXJ5KGJyYXlfY3VydGlzX3RvdGFsX2xtZV8xNXBlcmNfZXhjbCkKYW5vdmEoYnJheV9jdXJ0aXNfdG90YWxfbG1lXzE1cGVyY19leGNsKQoKYnJheV9jdXJ0aXNfdG90YWxfY29lZnNfMTVwZXJjX2V4Y2wgIDwtIGRhdGEudGFibGUoY29lZihicmF5X2N1cnRpc190b3RhbF9sbWVfMTVwZXJjX2V4Y2wpKQpicmF5X2N1cnRpc190b3RhbF9jb2Vmc18xNXBlcmNfZXhjbCBbLHN1cnZleV91bml0IDo9IHJvd25hbWVzKGNvZWYoYnJheV9jdXJ0aXNfdG90YWxfbG1lXzE1cGVyY19leGNsKSldWyxZZWFyIDo9IHJvdW5kKHllYXJfYWRqLDUpXVssSW50ZXJjZXB0IDo9IHJvdW5kKGAoSW50ZXJjZXB0KWAsMildCiNWaWV3KGJyYXlfY3VydGlzX3RvdGFsX2NvZWZzXzE1cGVyY19leGNsICkKCmJyYXlfY3VydGlzX3RvdGFsX2NvZWZzXzE1cGVyY19leGNsICA8LSBicmF5X2N1cnRpc190b3RhbF9jb2Vmc18xNXBlcmNfZXhjbCBbY29sb3JfbGluaywgb24gPSAic3VydmV5X3VuaXQiXQoKYnJheV9jdXJ0aXNfdG90YWxfY29lZnNfMTVwZXJjX2V4Y2wuZXhwIDwtIGJyYXlfY3VydGlzX3RvdGFsX2NvZWZzXzE1cGVyY19leGNsIFssLihTdXJ2ZXlfTmFtZV9TZWFzb24sIEludGVyY2VwdCwgWWVhcildCgojZXhwb3J0IHRoaXMgdGFibGUKZndyaXRlKGJyYXlfY3VydGlzX3RvdGFsX2NvZWZzXzE1cGVyY19leGNsLmV4cCwgZmlsZSA9IGhlcmU6OmhlcmUoIm91dHB1dCIsImJyYXlfY3VydGlzX3RvdGFsX2NvZWZzXzE1cGVyY19leGNsLmV4cC5jc3YiKSkKYGBgCgpHZXQgTE1FUiBtb2RlbCBhcyBwcmVkaWN0aW9ucwpgYGB7cn0KCiMgbmVlZCB0byBzb3J0IG91dCB5ZWFyIGluIHNlcSB2ZXJzdXMgb3ZlcmFsbCB5ZWFyIG1vZGVscwojbmV3IGRhdGEgZm9yIGxtZXIKbG1lcl95ZWFyIDwtIHNlcShtaW4oZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclsseWVhcl0pLCBtYXgoZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclsseWVhcl0pLCBieSA9IDAuMSkKCmxtZXJfeWVhcl9hZGogPC0gc2VxKG1pbihkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWyx5ZWFyX2Fkal0pLCBtYXgoZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclsseWVhcl9hZGpdKSwgYnkgPSAwLjEpCgojcHJlZGljdCBhdmVyYWdlIGxtZXIKbG1lcl9icmF5X3RvdGFsX3ByZWRpY3Rpb25zIDwtIGRhdGEudGFibGUoeWVhciA9IGxtZXJfeWVhciwgeWVhcl9hZGogPSBsbWVyX3llYXJfYWRqKQoKI2NvbmZpZGVuY2UgaW50ZXJ2YWxzCmJyYXlfY3VydGlzX3RvdGFsX2xtZXJfMTVwZXJjX2V4Y2xfY29uZmludCA8LSBjb25maW50KGJyYXlfY3VydGlzX3RvdGFsX2xtZXJfMTVwZXJjX2V4Y2wpCgojcG9wdWxhdGUgZGF0YSB0YWJsZSBvZiBsbWVyIHByZWRpY3Rpb25zCmxtZXJfYnJheV90b3RhbF9wcmVkaWN0aW9uc1ssYnJheV9jdXJ0aXNfbG1lcl9wcmVkcyA6PSBmaXhlZihicmF5X2N1cnRpc190b3RhbF9sbWVyXzE1cGVyY19leGNsKVtbMV1dICsgZml4ZWYoYnJheV9jdXJ0aXNfdG90YWxfbG1lcl8xNXBlcmNfZXhjbClbWzJdXSAqIHllYXJfYWRqXVssYnJheV9jdXJ0aXNfbG1lcl9wcmVkc19sb3dlckNJIDo9IGJyYXlfY3VydGlzX3RvdGFsX2xtZXJfMTVwZXJjX2V4Y2xfY29uZmludFs1XSArIGJyYXlfY3VydGlzX3RvdGFsX2xtZXJfMTVwZXJjX2V4Y2xfY29uZmludFs2XSAqIHllYXJfYWRqXVssYnJheV9jdXJ0aXNfbG1lcl9wcmVkc191cHBlckNJIDo9IGJyYXlfY3VydGlzX3RvdGFsX2xtZXJfMTVwZXJjX2V4Y2xfY29uZmludFsxMV0gKyBicmF5X2N1cnRpc190b3RhbF9sbWVyXzE1cGVyY19leGNsX2NvbmZpbnRbMTJdICogeWVhcl9hZGpdCmBgYAoKCgojIyNNb3ZlIGZvcndhcmQgd2l0aCBCcmF5IEN1cnRpcyB0b3RhbCBmb3Igb25seSA4NSUgbW9zdCBhYnVuZGFudCBzcGVjaWVzIGluIGVhY2ggcmVnaW9uCgoKQ29lZmZpY2llbnRzIGZvciBMTUVSIGJ5IHN1cnZleV91bml0CmBgYHtyfQojdW5pcXVlIHN1cnZleSB1bml0IHllYXIgY29tYm9zCnN1cnZleV91bml0X3NhbXBsaW5nX3llYXJzIDwtIHVuaXF1ZShkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWywuKHN1cnZleV91bml0LCB5ZWFyX2FkaiwgeWVhciwgeWVhcnNfc2FtcGxlZCldKQoKIyBzZWUgZ3JvdXAgY29lZmZpY2llbnRzCm1vZGVsX2NvZWZzX3JlZHVjZWQgPC0gZGF0YS50YWJsZSh0cmFuc2Zvcm0oYXMuZGF0YS5mcmFtZShyYW5lZihicmF5X2N1cnRpc190b3RhbF9sbWVyXzE1cGVyY19leGNsKSksIGx3ciA9IGNvbmR2YWwgLSAxLjk2KmNvbmRzZCwgdXByID0gY29uZHZhbCArIDEuOTYqY29uZHNkKSkKI2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzY5ODA1NTMyL2V4dHJhY3QtdGhlLWNvbmZpZGVuY2UtaW50ZXJ2YWxzLW9mLWxtZXItcmFuZG9tLWVmZmVjdHMtcGxvdHRlZC13aXRoLWRvdHBsb3RyYQoKCiNPTkxZIFNMT1BFUwptb2RlbF9jb2Vmc19yZWR1Y2VkIDwtIG1vZGVsX2NvZWZzX3JlZHVjZWRbdGVybSA9PSAieWVhcl9hZGoiLF0KCm1vZGVsX2NvZWZzX3JlZHVjZWRbLHN1cnZleV91bml0IDo9IGdycF1bLHllYXJfYWRqIDo9IGNvbmR2YWxdCgojbWVyZ2Ugd2l0aCBkdXJhdGlvbiBvZiBzdXJ2ZXkKbW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGggPC0gbW9kZWxfY29lZnNfcmVkdWNlZFtzdXJ2ZXlfdW5pdF9zYW1wbGluZ195ZWFycywgb24gPSAic3VydmV5X3VuaXQiXQoKCm1vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoWyx5ZWFyc19zYW1wbGVkIDo9IGFzLm51bWVyaWMoeWVhcnNfc2FtcGxlZCldWyxEaXJlY3Rpb25hbF9DaGFuZ2UgOj0gaWZlbHNlKHllYXJfYWRqID4gMCwgIkRpZmZlcmVudGlhdGlvbiIsIkhvbW9nZW5pemF0aW9uIildCgojZG9lcyBpdCBjcm9zcyB6ZXJvPwptb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aFssc2lnbmlmaWNhbnQgOj0gaWZlbHNlKGx3ciA+MCAmIHVwcj4wLFQsaWZlbHNlKGx3cjwwICYgdXByPDAsVCxGKSldCgojc2lnbmlmaWNhbnQgZGlyZWN0aW9uYWwgY2hhbmdlCm1vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoWyxEaXJlY3Rpb25hbF9DaGFuZ2Vfc2lnIDo9IGlmZWxzZSh5ZWFyX2FkaiA+IDAgJiBzaWduaWZpY2FudCA9PSBULCAiRGlmZmVyZW50aWF0aW9uIixpZmVsc2UoeWVhcl9hZGogPCAwICYgc2lnbmlmaWNhbnQgPT0gVCwgIkhvbW9nZW5pemF0aW9uIiwgIk5vIHRyZW5kIGluXG5kaXNzaW1pbGFyaXR5IikpXQoKCiNtaW4gbWF4IGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXMKbWluX2JyYXlfcmVkdWNlZCA8LSBtaW4oZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclssYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV90b3RhbF9tZWFuXSwgbmEucm0gPSBUKQptYXhfYnJheV9yZWR1Y2VkIDwtIG1heChkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWyxicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X3RvdGFsX21lYW5dLCBuYS5ybSA9IFQpCgptb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aCA8LSBtb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aFtjb2xvcl9saW5rLCBvbiA9ICJzdXJ2ZXlfdW5pdCJdCgojZGVsZXRlIGFueSBOQXMKbW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGggPC0gbmEub21pdChtb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aCwgY29scyA9ICJzaWduaWZpY2FudCIpCgojb3JkZXIgdGFibGUgYnkgY29lZmZpY2llbnQKc2V0b3JkZXIobW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGgsIHllYXJfYWRqKQoKQkNfdG90YWxfbW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGgudW5pcXVlXzE1cGVyY19leGNsIDwtIHVuaXF1ZShtb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aFssLihjb25kdmFsLGNvbmRzZCwgbHdyLCB1cHIsIHN1cnZleV91bml0LCB5ZWFyX2FkaiwgeWVhcnNfc2FtcGxlZCwgRGlyZWN0aW9uYWxfQ2hhbmdlLCBoZXgsIFN1cnZleV9OYW1lX1NlYXNvbiwgc2lnbmlmaWNhbnQsIERpcmVjdGlvbmFsX0NoYW5nZV9zaWcpXSkgCgojZXh0cmFjdCBjb2xvciBoZXhlcwojeWVhciBhZGogY29lZiBvcmRlcgpjb2xvcl95ZWFyX2Fkal9vcmRlciA8LSBCQ190b3RhbF9tb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aC51bmlxdWVfMTVwZXJjX2V4Y2xbLGhleF0KCiNhbHBoYWJldGljYWwgb3JkZXIKQkNfdG90YWxfbW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGgudW5pcXVlLmFscGhhIDwtIHNldG9yZGVyKEJDX3RvdGFsX21vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoLnVuaXF1ZV8xNXBlcmNfZXhjbCwgU3VydmV5X05hbWVfU2Vhc29uKQpjb2xvcl9hbHBoYV9vcmRlciA8LSBCQ190b3RhbF9tb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aC51bmlxdWUuYWxwaGFbLGhleF0KCiNhbHBoYWJldGljYWwgb3JkZXIKQkNfdG90YWxfbW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGgudW5pcXVlLmFscGhhXzE1cGVyY19leGNsIDwtIHNldG9yZGVyKEJDX3RvdGFsX21vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoLnVuaXF1ZV8xNXBlcmNfZXhjbCwgU3VydmV5X05hbWVfU2Vhc29uKQoKQkNfdG90YWxfbW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGgudW5pcXVlLmFscGhhXzE1cGVyY19leGNsWyx0cmVuZF9jb2xvciA6PSBpZmVsc2UoRGlyZWN0aW9uYWxfQ2hhbmdlX3NpZyA9PSAiSG9tb2dlbml6YXRpb24iLCAiI2U3YWM1YiIsIGlmZWxzZShEaXJlY3Rpb25hbF9DaGFuZ2Vfc2lnID09ICJEaWZmZXJlbnRpYXRpb24iLCIjOTFjODc0IiwiI2NiYmZkZSIpKV0KCmNvbG9yX2FscGhhX29yZGVyIDwtIEJDX3RvdGFsX21vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoLnVuaXF1ZS5hbHBoYV8xNXBlcmNfZXhjbFssaGV4XQpjb2xvcl9hbHBoYV9vcmRlcl9ieXRyZW5kIDwtIEJDX3RvdGFsX21vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoLnVuaXF1ZS5hbHBoYV8xNXBlcmNfZXhjbFssIHRyZW5kX2NvbG9yXQoKc2F2ZVJEUyhCQ190b3RhbF9tb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aC51bmlxdWVfMTVwZXJjX2V4Y2wsIGhlcmU6OmhlcmUoIm91dHB1dCIsInJlZ2lvbl9zdGF0cyIsIkJDX3RvdGFsX21vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoLnVuaXF1ZV8xNXBlcmNfZXhjbC5SZHMiKSkKYGBgCgpCYXIgUGxvdCBDb2VmZmljaWVudCBMTUVSCmBgYHtyIGJhciBwbG90IG9mIGNvZWZmaWNpZW50c30KQkNfdG90YWxfRGlzc2ltaWxhcml0eV9Db2VmX2Vycm9yYmFyX3JlZHVjZWRfMTVwZXJjX2V4Y2x1IDwtIGdncGxvdCgpICsKICAgIGdlb21fZXJyb3JiYXIoZGF0YSA9IG1vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoLCBhZXMoeCA9IHJlb3JkZXIoU3VydmV5X05hbWVfU2Vhc29uLCB5ZWFyX2FkaikgLCB5ID0geWVhcl9hZGosIGxhYmVsID0gU3VydmV5X05hbWVfU2Vhc29uLCB5bWluID0gbHdyLCB5bWF4ID0gdXByKSwgZmlsbCA9ICJncmV5Iiwgd2lkdGggPSAwKSArICNhZGQgY29uZmlkZW5jZSBpbnRlcnZhbHMKICBnZW9tX3BvaW50KGRhdGEgPSBtb2RlbF9jb2Vmc19yZWR1Y2VkX2xlbmd0aCwgYWVzKHggPSByZW9yZGVyKFN1cnZleV9OYW1lX1NlYXNvbiwgeWVhcl9hZGopICwgeSA9IHllYXJfYWRqLCBsYWJlbCA9IFN1cnZleV9OYW1lX1NlYXNvbiwgc2l6ZSA9IHllYXJzX3NhbXBsZWQsIGZpbGwgPSBEaXJlY3Rpb25hbF9DaGFuZ2Vfc2lnLCBjb2xvciA9IERpcmVjdGlvbmFsX0NoYW5nZV9zaWcpLCBzdGF0ID0gJ2lkZW50aXR5Jywgc2hhcGUgPSAyMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIndoaXRlIiwiYmxhY2siLCJncmV5IiksIG5hbWUgPSAiRGlzc2ltaWxhcml0eSB0cmVuZCIsIGd1aWRlPSJub25lIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsImJsYWNrIiwiZ3JleSIpLCBuYW1lID0gIkRpc3NpbWlsYXJpdHkgdHJlbmQiLCBndWlkZT0ibm9uZSIpICsKICBzY2FsZV9zaXplX2Jpbm5lZChyYW5nZSA9IGMoMSw4KSwgbmFtZSA9ICJTdXJ2ZXkgcGVyaW9kIGxlbmd0aCIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMC4wMDUsIDAuMDA3NSwgYnkgPSAwLjAwMjUpLCBsYWJlbHMgPSBjKCItMC4wMDUiLCIiLCIwIiwgIiIsICIwLjAwNSIsICAiIikpICsKICB4bGFiKCJTdXJ2ZXkgdW5pdCIpICsKICB5bGFiKCLOsi1kaXZlcnNpdHkgdHJlbmQiKSArICN0b3RhbCBCQyBkaXNzaW1pbGFyaXR5IHRyZW5kCiAgY29vcmRfZmxpcCgpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IGNvbG9yX3llYXJfYWRqX29yZGVyLCBmYWNlID0gImJvbGQiKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjI1LDAuNyksIGxlZ2VuZC5kaXJlY3Rpb24gPSAidmVydGljYWwiKQoKI3B1bGwgbGVnZW5kIGZvciBob21vZ2VuaXphdGlvbgpkaXJlY3Rpb25hbF9jaGFuZ2VfbGVnZW5kX3Bsb3RfMTVwZXJjX2V4Y2x1IDwtIEJDX3RvdGFsX0Rpc3NpbWlsYXJpdHlfQ29lZl9lcnJvcmJhcl9yZWR1Y2VkXzE1cGVyY19leGNsdSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIndoaXRlIiwiYmxhY2siLCJncmV5IiksIG5hbWUgPSAiRGlzc2ltaWxhcml0eSB0cmVuZCIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiYmxhY2siLCJibGFjayIsImdyZXkiKSwgbmFtZSA9ICJEaXNzaW1pbGFyaXR5IHRyZW5kIikgKwogIHNjYWxlX3NpemVfYmlubmVkKHJhbmdlID0gYygxLDgpLCBuYW1lID0gIlN1cnZleSBwZXJpb2QgbGVuZ3RoIiwgZ3VpZGUgPSAibm9uZSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSAidHJhbnNwYXJlbnQiKSkgKwogIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplPTYpKSkKCgpCQ190b3RhbF9EaXNzaW1pbGFyaXR5X0NvZWZfZXJyb3JiYXJfcmVkdWNlZF8xNXBlcmNfZXhjbHUKCiNBTFQgZ3JleSBzY2FsZQpCQ190b3RhbF9EaXNzaW1pbGFyaXR5X0NvZWZfZXJyb3JiYXJfcmVkdWNlZF9ncmV5c2NhbGVfMTVwZXJjX2V4Y2wgPC0gZ2dwbG90KCkgKwogICAgZ2VvbV9lcnJvcmJhcihkYXRhID0gbW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGgsIGFlcyh4ID0gcmVvcmRlcihTdXJ2ZXlfTmFtZV9TZWFzb24sIHllYXJfYWRqKSAsIHkgPSB5ZWFyX2FkaiwgbGFiZWwgPSBTdXJ2ZXlfTmFtZV9TZWFzb24sIHltaW4gPSBsd3IsIHltYXggPSB1cHIpLCBmaWxsID0gImdyZXkiLCB3aWR0aCA9IDApICsgI2FkZCBjb25maWRlbmNlIGludGVydmFscwogIGdlb21fcG9pbnQoZGF0YSA9IG1vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoLCBhZXMoeCA9IHJlb3JkZXIoU3VydmV5X05hbWVfU2Vhc29uLCB5ZWFyX2FkaikgLCB5ID0geWVhcl9hZGosIGxhYmVsID0gU3VydmV5X05hbWVfU2Vhc29uLCBzaXplID0geWVhcnNfc2FtcGxlZCwgZmlsbCA9IERpcmVjdGlvbmFsX0NoYW5nZV9zaWcsIGNvbG9yID0gRGlyZWN0aW9uYWxfQ2hhbmdlX3NpZyksIHN0YXQgPSAnaWRlbnRpdHknLCBzaGFwZSA9IDIxKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygid2hpdGUiLCJibGFjayIsImdyZXkiKSwgbmFtZSA9ICJEaXNzaW1pbGFyaXR5IHRyZW5kIiwgZ3VpZGU9Im5vbmUiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwiYmxhY2siLCJncmV5IiksIG5hbWUgPSAiRGlzc2ltaWxhcml0eSB0cmVuZCIsIGd1aWRlPSJub25lIikgKwogIHNjYWxlX3NpemVfYmlubmVkKHJhbmdlID0gYygxLDgpLCBuYW1lID0gIlN1cnZleSBwZXJpb2QgbGVuZ3RoIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKC0wLjAwNSwgMC4wMDc1LCBieSA9IDAuMDAyNSksIGxhYmVscyA9IGMoIi0wLjAwNSIsIiIsIjAiLCAiIiwgIjAuMDA1IiwgICIiKSkgKwogIHhsYWIoIlN1cnZleSB1bml0IikgKwogIHlsYWIoIs6yLWRpdmVyc2l0eSB0cmVuZCIpICsgI3RvdGFsIEJDIGRpc3NpbWlsYXJpdHkgdHJlbmQKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4yNSwwLjcpLCBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIikKYGBgCgpsdGVybmF0aXZlbHksIHdlIGNvbG9yICB0aGlzIHBsb3QgYnkgdHJlbmQgZXhwZXJpZW5jZWQKCmBgYHtyfQojIiM3M0JBNEQiLCIjRTA5NjJDIiwiI2NiYmZkZSIKCkJDX3RvdGFsX0Rpc3NpbWlsYXJpdHlfQ29lZl9lcnJvcmJhcl9yZWR1Y2VkX2NvbG9yYnl0cmVuZF8xNXBlcmNfZXhjbHUgPC0gZ2dwbG90KCkgKwogICAgZ2VvbV9lcnJvcmJhcihkYXRhID0gbW9kZWxfY29lZnNfcmVkdWNlZF9sZW5ndGgsIGFlcyh4ID0gcmVvcmRlcihTdXJ2ZXlfTmFtZV9TZWFzb24sIHllYXJfYWRqKSAsIHkgPSB5ZWFyX2FkaiwgbGFiZWwgPSBTdXJ2ZXlfTmFtZV9TZWFzb24sIHltaW4gPSBsd3IsIHltYXggPSB1cHIpLCBmaWxsID0gImdyZXkiLCB3aWR0aCA9IDApICsgI2FkZCBjb25maWRlbmNlIGludGVydmFscwogIGdlb21fcG9pbnQoZGF0YSA9IG1vZGVsX2NvZWZzX3JlZHVjZWRfbGVuZ3RoLCBhZXMoeCA9IHJlb3JkZXIoU3VydmV5X05hbWVfU2Vhc29uLCB5ZWFyX2FkaikgLCB5ID0geWVhcl9hZGosIGxhYmVsID0gU3VydmV5X05hbWVfU2Vhc29uLCBzaXplID0geWVhcnNfc2FtcGxlZCwgY29sb3IgPSBEaXJlY3Rpb25hbF9DaGFuZ2Vfc2lnKSwgc3RhdCA9ICdpZGVudGl0eScpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzczQkE0RCIsIiNFMDk2MkMiLCIjY2JiZmRlIiksIG5hbWUgPSAiRGlzc2ltaWxhcml0eSB0cmVuZCIsIGd1aWRlPSJub25lIikgKwogIHNjYWxlX3NpemVfYmlubmVkKHJhbmdlID0gYygxLDgpLCBuYW1lID0gIlN1cnZleSBwZXJpb2QgbGVuZ3RoXG4oeWVhcnMpIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKC0wLjAwNSwgMC4wMDc1LCBieSA9IDAuMDAyNSksIGxhYmVscyA9IGMoIi0wLjAwNSIsIiIsIjAiLCAiIiwgIjAuMDA1IiwgICIiKSkgKwogIHhsYWIoIlN1cnZleSB1bml0IikgKwogIHlsYWIoIs6yLWRpdmVyc2l0eSB0cmVuZCIpICsgI3RvdGFsIEJDIGRpc3NpbWlsYXJpdHkgdHJlbmQKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4zLDAuOCksIGxlZ2VuZC5kaXJlY3Rpb24gPSAidmVydGljYWwiLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSkKCmRpcmVjdGlvbmFsX2NoYW5nZV9sZWdlbmRfcGxvdF9jb2xvcmJ5dHJlbmRfMTVwZXJjX2V4Y2x1IDwtIEJDX3RvdGFsX0Rpc3NpbWlsYXJpdHlfQ29lZl9lcnJvcmJhcl9yZWR1Y2VkX2NvbG9yYnl0cmVuZF8xNXBlcmNfZXhjbHUgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSAidHJhbnNwYXJlbnQiKSwgCiAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpKSArCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9NikpLCBzaXplID0gIm5vbmUiKQpgYGAKCgpXYXZ5IExpbmUgUGxvdCBmb3IgR0FNcwoKR2VuZXJhdGUgcHJlZGljdGVkIHZhbHVlcwpgYGB7ciBnZW5lcmF0ZSBwcmVkaWN0ZWQgdmFsdWVzIEdBTX0KCiNhZGQgY29sb3JzIGFuZCBuYW1lcyB0byBmdWxsIGRpc3NpbWlsYXJpdHkgZGF0YSB0YWJsZQpkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yIDwtIGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnJbY29sb3JfbGluaywgb24gPSAic3VydmV5X3VuaXQiXQoKI2dlbmVyYXRlIG5ldyBkYXRhIHRvIHNtb290aCBsaW5lcyAobmVlZCB5ZWFyIGFuZCBzZWFzb24gc3VydmV5IGNvbWJpbmF0aW9ucykKeWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHQgPC0gZGF0YS50YWJsZShzdXJ2ZXlfdW5pdCA9IGFzLmNoYXJhY3RlcihOVUxMKSwgeWVhciA9IGFzLm51bWVyaWMoTlVMTCksIHllYXJfYWRqID0gYXMubnVtZXJpYyhOVUxMICkpCgpmb3IgKGkgaW4gMTpsZW5ndGgoc3VydmV5X3VuaXQubGlzdCkpIHsKICAjZ2VuZXJhdGUgeWVhciB2ZWN0b3JzCiAgc3VydmV5X3VuaXRfeWVhcnMgPC0gdW5pcXVlKGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnJbc3VydmV5X3VuaXQgPT0gc3VydmV5X3VuaXQubGlzdFtpXSwuKHN1cnZleV91bml0LCB5ZWFyLCB5ZWFyX2FkaildKQogIAogIHllYXJzIDwtIHNlcShtaW4oc3VydmV5X3VuaXRfeWVhcnNbLHllYXJdKSwgbWF4KHN1cnZleV91bml0X3llYXJzWyx5ZWFyXSksIGJ5ID0gMC4xKQogIAogIHllYXJfYWRqdXN0IDwtIHNlcShtaW4oc3VydmV5X3VuaXRfeWVhcnNbLHllYXJfYWRqXSksIG1heChzdXJ2ZXlfdW5pdF95ZWFyc1sseWVhcl9hZGpdKSwgYnkgPSAwLjEpCiAgCiAgeWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHRfYWRkaXRpb24gPC0gZGF0YS50YWJsZShzdXJ2ZXlfdW5pdCA9IHN1cnZleV91bml0Lmxpc3RbaV0sIHllYXIgPSB5ZWFycywgeWVhcl9hZGogPSB5ZWFyX2FkanVzdCkKICAKICB5ZWFyX3N1cnZleV91bml0X2V4cGFuZC5kdCA8LSByYmluZCh5ZWFyX3N1cnZleV91bml0X2V4cGFuZC5kdCwgeWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHRfYWRkaXRpb24pCn0KCiNhZGQgY29sb3JzIGFuZCBuYW1lcyB0byBmdWxsIHllYXIgYW5kIHN1cnZleSB1bml0IGNvbWJpbmF0aW9uIHRhYmxlCnllYXJfc3VydmV5X3VuaXRfZXhwYW5kLmR0IDwtIHllYXJfc3VydmV5X3VuaXRfZXhwYW5kLmR0W2NvbG9yX2xpbmssIG9uID0gInN1cnZleV91bml0Il0KYGBgCgpBbHRlcm5hdGl2ZSwgY29sb3IgYnkgdHJlbmQKYGBge3IgY29sb3Igd2F2eSBsaW5lcyBieSB0cmVuZH0KCnBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX2NvbG9yYnl0cmVuZF8xNXBlcmNfZXhjbCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yaWJib24oZGF0YSA9IGxtZXJfYnJheV90b3RhbF9wcmVkaWN0aW9ucywgYWVzKHggPSB5ZWFyLCB5bWluID0gYnJheV9jdXJ0aXNfbG1lcl9wcmVkc19sb3dlckNJLCB5bWF4ID0gYnJheV9jdXJ0aXNfbG1lcl9wcmVkc191cHBlckNJKSwgZmlsbCA9ICJncmV5IiwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3BvaW50KGRhdGEgPSBuYS5vbWl0KGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnIsIGNvbHMgPSAieWVhcl9hZGoiKSwKICAgICAgICAgICAgIGFlcyh4ID0geWVhciwKICAgICAgICAgICAgICAgICB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV90b3RhbF9tZWFuLAogICAgICAgICAgICAgICAgIGZpbGwgPSBTdXJ2ZXlfTmFtZV9TZWFzb24pLCBhbHBoYSA9IDAuNCwgc2l6ZSA9IDEsIHNoYXBlID0gMjEsIGNvbG9yID0gIndoaXRlIikgKwogICAgZ2VvbV9saW5lKGRhdGEgPSBuYS5vbWl0KHllYXJfc3VydmV5X3VuaXRfZXhwYW5kLmR0LCBjb2xzID0gInllYXJfYWRqIiksCiAgICAgICAgICAgICBhZXMoeCA9IHllYXIsCiAgICAgICAgICAgICAgICAgeSA9IGJyYXlfZ2xtX21vZF9maXQsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBTdXJ2ZXlfTmFtZV9TZWFzb24pLCBhbHBoYSA9IDAuNikgKwogIGdlb21fcmliYm9uKGRhdGEgPSBuYS5vbWl0KHllYXJfc3VydmV5X3VuaXRfZXhwYW5kLmR0LCBjb2xzID0gInllYXJfYWRqIiksIGFlcyh4ID0geWVhciwgeW1pbj1icmF5X2dsbV9tb2RfZml0LWJyYXlfZ2xtX21vZF9maXRfU0UsIHltYXg9YnJheV9nbG1fbW9kX2ZpdCticmF5X2dsbV9tb2RfZml0X1NFLCBmaWxsID0gIFN1cnZleV9OYW1lX1NlYXNvbiksIGFscGhhPTAuMSkgKyAjYWRkIHN0YW5kYXJkIGVycm9yCiAgZ2VvbV9saW5lKGRhdGEgPSBsbWVyX2JyYXlfdG90YWxfcHJlZGljdGlvbnMsIGFlcyh4ID0geWVhciwgeSA9IGJyYXlfY3VydGlzX2xtZXJfcHJlZHMpLCBjb2xvciA9ICJibGFjayIpICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSAgY29sb3JfYWxwaGFfb3JkZXJfYnl0cmVuZCwgbmFtZSA9ICJTdXJ2ZXkgVW5pdCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSAgY29sb3JfYWxwaGFfb3JkZXJfYnl0cmVuZCwgZ3VpZGUgPSAibm9uZSIpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIGxpbXMoeCA9IGMobWluKGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnJbLHllYXJdKSxtYXgoZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclsseWVhcl0pKSkgKwogIHhsYWIoIlllYXIiKSArCnlsYWIoIs6yLWRpdmVyc2l0eSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibnVsbCIsIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCgpwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9jb2xvcmJ5dHJlbmRfMTVwZXJjX2V4Y2wKCmdnc2F2ZShwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9jb2xvcmJ5dHJlbmRfMTVwZXJjX2V4Y2wsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0icG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1fY29sb3JieXRyZW5kXzE1cGVyY19leGNsLmpwZyIsIGhlaWdodCA9IDYsIHdpZHRoID0gNiwgdW5pdCA9ICJpbiIpCmBgYAoKR2V0IG1vZGVsIGFzIHByZWRpY3Rpb25zCmBgYHtyfQojZm9yIHBsb3R0aW5nLCBnZXQgbW9kZWwgYXMgcHJlZGljdGlvbnMKYnJheV9jdXJ0aXNfdG90YWxfZ2FtXzE1cGVyY19leGNsX3ByZWRpY3Rpb25zIDwtIHByZWRpY3QoYnJheV9jdXJ0aXNfdG90YWxfZ2FtXzE1cGVyY19leGNsLCBzZS5maXQgPSBUUlVFLCBuZXdkYXRhID0geWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHQpCgojbWVyZ2UgaW50byB0YWJsZQp5ZWFyX3N1cnZleV91bml0X2V4cGFuZC5kdFssYnJheV9nbG1fbW9kX2ZpdCA6PSBicmF5X2N1cnRpc190b3RhbF9nYW1fMTVwZXJjX2V4Y2xfcHJlZGljdGlvbnMkZml0XVssYnJheV9nbG1fbW9kX2ZpdF9TRSA6PSBicmF5X2N1cnRpc190b3RhbF9nYW1fMTVwZXJjX2V4Y2xfcHJlZGljdGlvbnMkc2UuZml0XQoKYGBgCgoKUHJvZHVjZSBQbG90IG9mIEdBTSBhbmQgbWVhbiBMTUVSIGxpbmUKYGBge3IgcGxvdCBHQU0gYW5kIG1lYW4gTE1FUiBsaW5lc30KcG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1fbm9sbWVyXzE1cGVyY19leGNsIDwtIGdncGxvdCgpICsKICMgZ2VvbV9yaWJib24oZGF0YSA9IGxtZXJfYnJheV90b3RhbF9wcmVkaWN0aW9ucywgYWVzKHggPSB5ZWFyLCB5bWluID0gYnJheV9jdXJ0aXNfbG1lcl9wcmVkc19sb3dlckNJLCB5bWF4ID0gYnJheV9jdXJ0aXNfbG1lcl9wcmVkc191cHBlckNJKSwgZmlsbCA9ICJncmV5IiwgYWxwaGEgPSAwLjIpICsKICBnZW9tX3BvaW50KGRhdGEgPSBuYS5vbWl0KGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnIsY29scyA9ICJ5ZWFyX2FkaiIpLAogICAgICAgICAgICAgYWVzKHggPSB5ZWFyLAogICAgICAgICAgICAgICAgIHkgPSBicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X3RvdGFsX21lYW4sCiAgICAgICAgICAgICAgICAgY29sb3IgPSBTdXJ2ZXlfTmFtZV9TZWFzb24pLCBhbHBoYSA9IDAuNSwgc2l6ZSA9IDEpICsKICAgIGdlb21fbGluZShkYXRhID0gbmEub21pdCh5ZWFyX3N1cnZleV91bml0X2V4cGFuZC5kdCxjb2xzID0gInllYXJfYWRqIiksCiAgICAgICAgICAgICBhZXMoeCA9IHllYXIsCiAgICAgICAgICAgICAgICAgeSA9IGJyYXlfZ2xtX21vZF9maXQsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBTdXJ2ZXlfTmFtZV9TZWFzb24pKSArCiAgZ2VvbV9yaWJib24oZGF0YSA9IG5hLm9taXQoeWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHQsY29scyA9ICJ5ZWFyX2FkaiIpLCBhZXMoeCA9IHllYXIsIHltaW49YnJheV9nbG1fbW9kX2ZpdC1icmF5X2dsbV9tb2RfZml0X1NFLCB5bWF4PWJyYXlfZ2xtX21vZF9maXQrYnJheV9nbG1fbW9kX2ZpdF9TRSwgZmlsbCA9ICBTdXJ2ZXlfTmFtZV9TZWFzb24pLCBhbHBoYT0wLjEpICsgI2FkZCBzdGFuZGFyZCBlcnJvcgogIyBnZW9tX2xpbmUoZGF0YSA9IGxtZXJfYnJheV90b3RhbF9wcmVkaWN0aW9ucywgYWVzKHggPSB5ZWFyLCB5ID0gYnJheV9jdXJ0aXNfbG1lcl9wcmVkcyksIGNvbG9yID0gImJsYWNrIikgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9ICBjb2xvcl9hbHBoYV9vcmRlciwgbmFtZSA9ICJTdXJ2ZXkgVW5pdCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSAgY29sb3JfYWxwaGFfb3JkZXIsIGd1aWRlID0gIm5vbmUiKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBsaW1zKHggPSBjKG1pbihkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWyx5ZWFyXSksbWF4KGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnJbLHllYXJdKSksCiAgICAgICB5ID0gYygwLjE1LDAuOSkpICsKICB4bGFiKCJZZWFyIikgKwp5bGFiKCJ0b3RhbCBCQyBkaXNzaW1pbGFyaXR5IikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJudWxsIikKCnBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX25vbG1lcl8xNXBlcmNfZXhjbAoKZ2dzYXZlKHBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX25vbG1lcl8xNXBlcmNfZXhjbCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSJwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9ub2xtZXJfMTVwZXJjX2V4Y2wuanBnIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA1LCB1bml0ID0gImluIikKCiN3aXRoIGxtZXIKCnBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtXzE1cGVyY19leGNsIDwtIGdncGxvdCgpICsKICBnZW9tX3JpYmJvbihkYXRhID0gbG1lcl9icmF5X3RvdGFsX3ByZWRpY3Rpb25zLCBhZXMoeCA9IHllYXIsIHltaW4gPSBicmF5X2N1cnRpc19sbWVyX3ByZWRzX2xvd2VyQ0ksIHltYXggPSBicmF5X2N1cnRpc19sbWVyX3ByZWRzX3VwcGVyQ0kpLCBmaWxsID0gImdyZXkiLCBhbHBoYSA9IDAuMykgKwogIGdlb21fcG9pbnQoZGF0YSA9IG5hLm9taXQoZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuciwgY29scyA9ICJ5ZWFyX2FkaiIpLAogICAgICAgICAgICAgYWVzKHggPSB5ZWFyLAogICAgICAgICAgICAgICAgIHkgPSBicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X3RvdGFsX21lYW4sCiAgICAgICAgICAgICAgICAgZmlsbCA9IFN1cnZleV9OYW1lX1NlYXNvbiksIGFscGhhID0gMC40LCBzaXplID0gMSwgc2hhcGUgPSAyMSwgY29sb3IgPSAid2hpdGUiKSArCiAgICBnZW9tX2xpbmUoZGF0YSA9IG5hLm9taXQoeWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHQsIGNvbHMgPSAieWVhcl9hZGoiKSwKICAgICAgICAgICAgIGFlcyh4ID0geWVhciwKICAgICAgICAgICAgICAgICB5ID0gYnJheV9nbG1fbW9kX2ZpdCwKICAgICAgICAgICAgICAgICBjb2xvciA9IFN1cnZleV9OYW1lX1NlYXNvbiksIGFscGhhID0gMC42KSArCiAgZ2VvbV9yaWJib24oZGF0YSA9IG5hLm9taXQoeWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHQsIGNvbHMgPSAieWVhcl9hZGoiKSwgYWVzKHggPSB5ZWFyLCB5bWluPWJyYXlfZ2xtX21vZF9maXQtYnJheV9nbG1fbW9kX2ZpdF9TRSwgeW1heD1icmF5X2dsbV9tb2RfZml0K2JyYXlfZ2xtX21vZF9maXRfU0UsIGZpbGwgPSAgU3VydmV5X05hbWVfU2Vhc29uKSwgYWxwaGE9MC4xKSArICNhZGQgc3RhbmRhcmQgZXJyb3IKICBnZW9tX2xpbmUoZGF0YSA9IGxtZXJfYnJheV90b3RhbF9wcmVkaWN0aW9ucywgYWVzKHggPSB5ZWFyLCB5ID0gYnJheV9jdXJ0aXNfbG1lcl9wcmVkcyksIGNvbG9yID0gImJsYWNrIikgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9ICBjb2xvcl9hbHBoYV9vcmRlciwgbmFtZSA9ICJTdXJ2ZXkgVW5pdCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSAgY29sb3JfYWxwaGFfb3JkZXIsIGd1aWRlID0gIm5vbmUiKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBsaW1zKHggPSBjKG1pbihkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWyx5ZWFyXSksbWF4KGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnJbLHllYXJdKSkpICsKICB4bGFiKCJZZWFyIikgKwp5bGFiKCLOsi1kaXZlcnNpdHkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm51bGwiLCBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQoKcG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1fMTVwZXJjX2V4Y2wKCmdnc2F2ZShwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV8xNXBlcmNfZXhjbCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSJwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV8xNXBlcmNfZXhjbC5qcGciLCBoZWlnaHQgPSA2LCB3aWR0aCA9IDYsIHVuaXQgPSAiaW4iKQoKI0FMVAojcGxvdCBhbGwsIGJ1dCBzYW1lIGNvbG9yIHNjaGVtZSAoZ3JleSkKcG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1fZ3JleXNjYWxlXzE1cGVyY19leGNsIDwtIGdncGxvdCgpICsKICBnZW9tX3JpYmJvbihkYXRhID0gbG1lcl9icmF5X3RvdGFsX3ByZWRpY3Rpb25zLCBhZXMoeCA9IHllYXIsIHltaW4gPSBicmF5X2N1cnRpc19sbWVyX3ByZWRzX2xvd2VyQ0ksIHltYXggPSBicmF5X2N1cnRpc19sbWVyX3ByZWRzX3VwcGVyQ0kpLCBmaWxsID0gImdyZXkiLCBhbHBoYSA9IDAuMykgKwogIGdlb21fcG9pbnQoZGF0YSA9IGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnIsCiAgICAgICAgICAgICBhZXMoeCA9IHllYXIsCiAgICAgICAgICAgICAgICAgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfdG90YWxfbWVhbiwKICAgICAgICAgICAgICAgICBmaWxsID0gU3VydmV5X05hbWVfU2Vhc29uKSwgYWxwaGEgPSAwLjQsIHNpemUgPSAxLCBzaGFwZSA9IDIxLCBjb2xvciA9ICJ3aGl0ZSIpICsKICAgIGdlb21fbGluZShkYXRhID0geWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHQsCiAgICAgICAgICAgICBhZXMoeCA9IHllYXIsCiAgICAgICAgICAgICAgICAgeSA9IGJyYXlfZ2xtX21vZF9maXQsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBTdXJ2ZXlfTmFtZV9TZWFzb24pLCBhbHBoYSA9IDAuNikgKwogIGdlb21fcmliYm9uKGRhdGEgPSB5ZWFyX3N1cnZleV91bml0X2V4cGFuZC5kdCwgYWVzKHggPSB5ZWFyLCB5bWluPWJyYXlfZ2xtX21vZF9maXQtYnJheV9nbG1fbW9kX2ZpdF9TRSwgeW1heD1icmF5X2dsbV9tb2RfZml0K2JyYXlfZ2xtX21vZF9maXRfU0UsIGZpbGwgPSAgU3VydmV5X05hbWVfU2Vhc29uKSwgYWxwaGE9MC4xKSArICNhZGQgc3RhbmRhcmQgZXJyb3IKICBnZW9tX2xpbmUoZGF0YSA9IGxtZXJfYnJheV90b3RhbF9wcmVkaWN0aW9ucywgYWVzKHggPSB5ZWFyLCB5ID0gYnJheV9jdXJ0aXNfbG1lcl9wcmVkcyksIGNvbG9yID0gImJsYWNrIikgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9ICByZXAoImJsYWNrIiwgdGltZXMgPSBsZW5ndGgodW5pcXVlKGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnIkU3VydmV5X05hbWVfU2Vhc29uKSkpLCBuYW1lID0gIlN1cnZleSBVbml0IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9ICByZXAoImJsYWNrIiwgdGltZXMgPSBsZW5ndGgodW5pcXVlKGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnIkU3VydmV5X05hbWVfU2Vhc29uKSkpLCBndWlkZSA9ICJub25lIikgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgbGltcyh4ID0gYyhtaW4oZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQuclsseWVhcl0pLG1heChkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yWyx5ZWFyXSkpCiAgICAgICApICsKICB4bGFiKCJZZWFyIikgKwp5bGFiKCLOsi1kaXZlcnNpdHkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm51bGwiLCBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQoKcG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1fZ3JleXNjYWxlXzE1cGVyY19leGNsCgpnZ3NhdmUocG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1fZ3JleXNjYWxlXzE1cGVyY19leGNsLCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9InBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX2dyZXlzY2FsZV8xNXBlcmNfZXhjbC5qcGciLCBoZWlnaHQgPSA2LCB3aWR0aCA9IDYsIHVuaXQgPSAiaW4iKQpgYGAKCmBgYHtyIHBsb3QgZWFjaCBpbmRlcGVuZGVudGx5fQojcGxvdCBlYWNoIGluZGVwZW5kZW50bHkgZm9yIHN1cHBsZW1lbnQKI2FsbCBzdXJ2ZXkgbmFtZXMgPSAKYWxsX3N1cnZleV9uYW1lcyA8LSBzb3J0KHVuaXF1ZShjb2xvcl9saW5rJFN1cnZleV9OYW1lX1NlYXNvbikpCiNsaXN0IG9mIHBsb3RzCnBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX2luZGl2aWR1YWxfMTVwZXJjX2V4Y2x1IDwtIGxpc3QoKQpmb3IgKGkgaW4gMTpsZW5ndGgoYWxsX3N1cnZleV9uYW1lcykpIHsKcG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1faW5kaXZpZHVhbF8xNXBlcmNfZXhjbHVbW2ldXSA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2ludChkYXRhID0gZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQucltTdXJ2ZXlfTmFtZV9TZWFzb24gPT0gYWxsX3N1cnZleV9uYW1lc1tpXV0sCiAgICAgICAgICAgICBhZXMoeCA9IHllYXIsCiAgICAgICAgICAgICAgICAgeSA9IGJyYXlfY3VydGlzX2Rpc3NpbWlsYXJpdHlfdG90YWxfbWVhbiksIGFscGhhID0gMC40LCBjb2xvciA9ICJibGFjayIpICsKICAgIGdlb21fbGluZShkYXRhID0geWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHRbU3VydmV5X05hbWVfU2Vhc29uID09IGFsbF9zdXJ2ZXlfbmFtZXNbaV1dLAogICAgICAgICAgICAgYWVzKHggPSB5ZWFyLAogICAgICAgICAgICAgICAgIHkgPSBicmF5X2dsbV9tb2RfZml0KSwgYWxwaGEgPSAwLjYpICsKICBnZW9tX3JpYmJvbihkYXRhID0geWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHRbU3VydmV5X05hbWVfU2Vhc29uID09IGFsbF9zdXJ2ZXlfbmFtZXNbaV1dLCBhZXMoeCA9IHllYXIsIHltaW49YnJheV9nbG1fbW9kX2ZpdC1icmF5X2dsbV9tb2RfZml0X1NFLCB5bWF4PWJyYXlfZ2xtX21vZF9maXQrYnJheV9nbG1fbW9kX2ZpdF9TRSksIGFscGhhPTAuMSkgKyAjYWRkIHN0YW5kYXJkIGVycm9yCiAgdGhlbWVfY2xhc3NpYygpICsKIyAgbGltcyh4ID0gYyhtaW4oZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQucltTdXJ2ZXlfTmFtZV9TZWFzb24gPT0gYWxsX3N1cnZleV9uYW1lc1tpXSx5ZWFyXSksbWF4KGRpc3RhbmNlc19kaXNzaW1pbGFyaXRpZXNfYWxseWVhcnNfMTVwZXJjX2V4Y2x1ZGVkLnJbU3VydmV5X05hbWVfU2Vhc29uID09IGFsbF9zdXJ2ZXlfbmFtZXNbaV0seWVhcl0pKSwKIyAgICAgICB5ID0gYygwLjE1LDAuOSkpICsKICB4bGFiKCJZZWFyIikgKwp5bGFiKCJiZXRhLWRpdmVyc2l0eSIpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIG5jb2wgPSA1KSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm51bGwiLCBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQoKcHJpbnQocG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1faW5kaXZpZHVhbF8xNXBlcmNfZXhjbHVbW2ldXSkKCn0Kc2F2ZVJEUyhwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9pbmRpdmlkdWFsXzE1cGVyY19leGNsdSwgaGVyZTo6aGVyZSgiZmlndXJlcyIsInBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX2luZGl2aWR1YWxfMTVwZXJjX2V4Y2x1LlJkcyIpKQoKI3ByaW50IHRvIHBkZgpsaWJyYXJ5KGdyaWRFeHRyYSkKCmdnc2F2ZSgKICAgZmlsZW5hbWUgPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiwicG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1faW5kaXZpZHVhbF8xNXBlcmNfZXhjbHUucGRmIiksIAogICBwbG90ID0gbWFycmFuZ2VHcm9iKHBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX2luZGl2aWR1YWxfMTVwZXJjX2V4Y2x1LCBucm93PTEsIG5jb2w9MSksIAogICB3aWR0aCA9IDguNSwgaGVpZ2h0ID0gMTEKKQoKI0FsdGVybmF0aXZlbHksIHNwbGl0IGludG8gMiBhbmQgdXNlIGZhY2V0CiNmaXJzdCAyNApwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9pbmRpdmlkdWFsX2ZhY2V0XzFfMjRfMTVwZXJjX2V4Y2x1IDwtIGdncGxvdCgpICsKICBnZW9tX3BvaW50KGRhdGEgPSBkaXN0YW5jZXNfZGlzc2ltaWxhcml0aWVzX2FsbHllYXJzXzE1cGVyY19leGNsdWRlZC5yW1N1cnZleV9OYW1lX1NlYXNvbiAgJWluJSBhbGxfc3VydmV5X25hbWVzW2MoMToyNCldXSwKICAgICAgICAgICAgIGFlcyh4ID0geWVhciwKICAgICAgICAgICAgICAgICB5ID0gYnJheV9jdXJ0aXNfZGlzc2ltaWxhcml0eV90b3RhbF9tZWFuKSwgYWxwaGEgPSAwLjcpICsKICAgIGdlb21fbGluZShkYXRhID0geWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHRbU3VydmV5X05hbWVfU2Vhc29uICAgJWluJSBhbGxfc3VydmV5X25hbWVzW2MoMToyNCldXSwKICAgICAgICAgICAgIGFlcyh4ID0geWVhciwKICAgICAgICAgICAgICAgICB5ID0gYnJheV9nbG1fbW9kX2ZpdCkpICsKICBnZW9tX3JpYmJvbihkYXRhID0geWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHRbU3VydmV5X05hbWVfU2Vhc29uICAlaW4lIGFsbF9zdXJ2ZXlfbmFtZXNbYygxOjI0KV1dLAphZXMoeCA9IHllYXIsIHltaW49YnJheV9nbG1fbW9kX2ZpdC1icmF5X2dsbV9tb2RfZml0X1NFLCB5bWF4PWJyYXlfZ2xtX21vZF9maXQrYnJheV9nbG1fbW9kX2ZpdF9TRSksIGFscGhhPTAuNSkgKyAjYWRkIHN0YW5kYXJkIGVycm9yCiAgdGhlbWVfY2xhc3NpYygpICsKICB4bGFiKCJZZWFyIikgKwp5bGFiKCLOsi1kaXZlcnNpdHkiKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQoKZ2dzYXZlKHBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX2luZGl2aWR1YWxfZmFjZXRfMV8yNF8xNXBlcmNfZXhjbHUsIHBhdGggPSAgaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9pbmRpdmlkdWFsX2ZhY2V0XzFfMjRfMTVwZXJjX2V4Y2x1LnBuZyIsIGhlaWdodCA9IDExLCB3aWR0aCA9IDkpCgpwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9pbmRpdmlkdWFsX2ZhY2V0XzI1XzQyXzE1cGVyY19leGNsdSA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2ludChkYXRhID0gZGlzdGFuY2VzX2Rpc3NpbWlsYXJpdGllc19hbGx5ZWFyc18xNXBlcmNfZXhjbHVkZWQucltTdXJ2ZXlfTmFtZV9TZWFzb24gICVpbiUgYWxsX3N1cnZleV9uYW1lc1tjKDI1OjQyKV1dLAogICAgICAgICAgICAgYWVzKHggPSB5ZWFyLAogICAgICAgICAgICAgICAgIHkgPSBicmF5X2N1cnRpc19kaXNzaW1pbGFyaXR5X3RvdGFsX21lYW4pLCBhbHBoYSA9IDAuNykgKwogICAgZ2VvbV9saW5lKGRhdGEgPSB5ZWFyX3N1cnZleV91bml0X2V4cGFuZC5kdFtTdXJ2ZXlfTmFtZV9TZWFzb24gICAlaW4lIGFsbF9zdXJ2ZXlfbmFtZXNbYygyNTo0MildXSwKICAgICAgICAgICAgIGFlcyh4ID0geWVhciwKICAgICAgICAgICAgICAgICB5ID0gYnJheV9nbG1fbW9kX2ZpdCkpICsKICBnZW9tX3JpYmJvbihkYXRhID0geWVhcl9zdXJ2ZXlfdW5pdF9leHBhbmQuZHRbU3VydmV5X05hbWVfU2Vhc29uICAlaW4lIGFsbF9zdXJ2ZXlfbmFtZXNbYygyNTo0MildXSwKYWVzKHggPSB5ZWFyLCB5bWluPWJyYXlfZ2xtX21vZF9maXQtYnJheV9nbG1fbW9kX2ZpdF9TRSwgeW1heD1icmF5X2dsbV9tb2RfZml0K2JyYXlfZ2xtX21vZF9maXRfU0UpLCBhbHBoYT0wLjUpICsgI2FkZCBzdGFuZGFyZCBlcnJvcgogIHRoZW1lX2NsYXNzaWMoKSArCiAgeGxhYigiWWVhciIpICsKeWxhYigizrItZGl2ZXJzaXR5IikgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKCmdnc2F2ZShwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9pbmRpdmlkdWFsX2ZhY2V0XzI1XzQyXzE1cGVyY19leGNsdSwgcGF0aCA9ICBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX2luZGl2aWR1YWxfZmFjZXRfMjVfNDJfMTVwZXJjX2V4Y2x1LnBuZyIsIGhlaWdodCA9IDExLCB3aWR0aCA9IDkpCgoKYGBgCgoKTWVyZ2UgQkMgdmVyc3VzIFllYXIgcGxvdCB3aXRoIEdBTVMgYW5kIFJlZ2lvbiB2cy4gY29lZmZpY2llbnQgcGxvdCBmb3IgTE1FUnMKCmBgYHtyfQoKQkNfdG90YWxfR0FNX0xNRVJfbWVyZ2VfbGVnZW5kXzE1cGVyY19leGNsIDwtIGdnZHJhdyh4bGltID0gYygwLCA0MC41KSwgeWxpbSA9IGMoMCwgMjEpKSArCiAgICBkcmF3X3Bsb3QocG9pbnRzX3dhdnlsaW5lc19icmF5X3RvdGFsX3llYXJfcmVkdWNlZF9nYW1fMTVwZXJjX2V4Y2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IDEsIHkgPSAxLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAyMCkgKwogICAgZHJhd19wbG90KEJDX3RvdGFsX0Rpc3NpbWlsYXJpdHlfQ29lZl9lcnJvcmJhcl9yZWR1Y2VkXzE1cGVyY19leGNsICsKICAgICAgICB0aGVtZShsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuNSwgJ2NtJyksICNjaGFuZ2UgbGVnZW5kIGtleSBzaXplCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLCAjY2hhbmdlIGxlZ2VuZCB0aXRsZSBmb250IHNpemUKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSksICNjaGFuZ2UgbGVnZW5kIHRleHQgZm9udCBzaXplKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gMjAsIHkgPSAxLCB3aWR0aCA9IDE5LCBoZWlnaHQgPSAyMCkgKwogICAgZHJhd19wbG90KGdldF9sZWdlbmQoZGlyZWN0aW9uYWxfY2hhbmdlX2xlZ2VuZF9wbG90XzE1cGVyY19leGNsICsgCiAgICAgIHRoZW1lKGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC41LCAnY20nKSwgI2NoYW5nZSBsZWdlbmQga2V5IHNpemUKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksICNjaGFuZ2UgbGVnZW5kIHRpdGxlIGZvbnQgc2l6ZQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpKSksICNjaGFuZ2UgbGVnZW5kIHRleHQgZm9udCBzaXplKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAyNywgeSA9IDEwLCB3aWR0aCA9IDMsIGhlaWdodCA9IDIpICsKICBnZW9tX3RleHQoYWVzKHggPSAyLCB5ID0gMjAuNyksIGxhYmVsID0gKCJhLiIpLCBzaXplID04LCBmb250ZmFjZSA9ICJib2xkIikgKwogIGdlb21fdGV4dChhZXMoeCA9MjAsIHkgPSAyMC43KSwgbGFiZWwgPSAoImIuIiksIHNpemUgPTgsIGZvbnRmYWNlID0gImJvbGQiKQoKCmdnc2F2ZShCQ190b3RhbF9HQU1fTE1FUl9tZXJnZV9sZWdlbmRfMTVwZXJjX2V4Y2x1LCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJCQ190b3RhbF9HQU1fTE1FUl9tZXJnZV9sZWdlbmRfMTVwZXJjX2V4Y2x1LnBuZyIsIGhlaWdodCA9IDgsIHdpZHRoID0gMTQsIHVuaXRzID0gImluIikKCiNBTFQgR1JFWSBTQ0FMRQpCQ190b3RhbF9HQU1fTE1FUl9tZXJnZV9sZWdlbmRfZ3JleXNjYWxlXzE1cGVyY19leGNsdSA8LSBnZ2RyYXcoeGxpbSA9IGMoMCwgNDAuNSksIHlsaW0gPSBjKDAsIDIxKSkgKwogICAgZHJhd19wbG90KHBvaW50c193YXZ5bGluZXNfYnJheV90b3RhbF95ZWFyX3JlZHVjZWRfZ2FtX2dyZXlzY2FsZV8xNXBlcmNfZXhjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gMSwgeSA9IDEsIHdpZHRoID0gMjAsIGhlaWdodCA9IDIwKSArCiAgICBkcmF3X3Bsb3QoQkNfdG90YWxfRGlzc2ltaWxhcml0eV9Db2VmX2Vycm9yYmFyX3JlZHVjZWRfZ3JleXNjYWxlXzE1cGVyY19leGNsICsKICAgICAgICB0aGVtZShsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuNSwgJ2NtJyksICNjaGFuZ2UgbGVnZW5kIGtleSBzaXplCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLCAjY2hhbmdlIGxlZ2VuZCB0aXRsZSBmb250IHNpemUKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSksICNjaGFuZ2UgbGVnZW5kIHRleHQgZm9udCBzaXplKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gMjAsIHkgPSAxLCB3aWR0aCA9IDE5LCBoZWlnaHQgPSAyMCkgKwogICAgZHJhd19wbG90KGdldF9sZWdlbmQoZGlyZWN0aW9uYWxfY2hhbmdlX2xlZ2VuZF9wbG90XzE1cGVyY19leGNsICsgCiAgICAgIHRoZW1lKGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC41LCAnY20nKSwgI2NoYW5nZSBsZWdlbmQga2V5IHNpemUKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSksICNjaGFuZ2UgbGVnZW5kIHRpdGxlIGZvbnQgc2l6ZQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTMpKSksICNjaGFuZ2UgbGVnZW5kIHRleHQgZm9udCBzaXplKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAyNywgeSA9IDEwLCB3aWR0aCA9IDMsIGhlaWdodCA9IDIpICsKICBnZW9tX3RleHQoYWVzKHggPSAyLCB5ID0gMjAuNyksIGxhYmVsID0gKCJhLiIpLCBzaXplID04LCBmb250ZmFjZSA9ICJib2xkIikgKwogIGdlb21fdGV4dChhZXMoeCA9MjAsIHkgPSAyMC43KSwgbGFiZWwgPSAoImIuIiksIHNpemUgPTgsIGZvbnRmYWNlID0gImJvbGQiKQoKZ2dzYXZlKEJDX3RvdGFsX0dBTV9MTUVSX21lcmdlX2xlZ2VuZF9ncmV5c2NhbGVfMTVwZXJjX2V4Y2x1LCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJCQ190b3RhbF9HQU1fTE1FUl9tZXJnZV9sZWdlbmRfZ3JleXNjYWxlXzE1cGVyY19leGNsdS5wbmciLCBoZWlnaHQgPSA4LCB3aWR0aCA9IDE0LCB1bml0cyA9ICJpbiIpCgpCQ190b3RhbF9HQU1fTE1FUl9tZXJnZV9sZWdlbmRfZ3JleXNjYWxlXzE1cGVyY19leGNsdQoKCiNBTFQgQ09MT1IgQlkgVFJFTkQKQkNfdG90YWxfR0FNX0xNRVJfbWVyZ2VfbGVnZW5kX2NvbG9yYnl0cmVuZF8xNXBlcmNfZXhjbHUgPC0gZ2dkcmF3KHhsaW0gPSBjKDAsIDQwLjUpLCB5bGltID0gYygwLCAyMSkpICsKICAgIGRyYXdfcGxvdChwb2ludHNfd2F2eWxpbmVzX2JyYXlfdG90YWxfeWVhcl9yZWR1Y2VkX2dhbV9jb2xvcmJ5dHJlbmRfMTVwZXJjX2V4Y2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IDEsIHkgPSAxLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAyMCkgKwogICAgZHJhd19wbG90KEJDX3RvdGFsX0Rpc3NpbWlsYXJpdHlfQ29lZl9lcnJvcmJhcl9yZWR1Y2VkX2NvbG9yYnl0cmVuZF8xNXBlcmNfZXhjbHUgKwogICAgICAgIHRoZW1lKGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC41LCAnY20nKSwgI2NoYW5nZSBsZWdlbmQga2V5IHNpemUKICAgICAgICMgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLCAjY2hhbmdlIGxlZ2VuZCB0aXRsZSBmb250IHNpemUKICAgICAgICMgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkKICAgICAgICksICNjaGFuZ2UgbGVnZW5kIHRleHQgZm9udCBzaXplKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gMjAsIHkgPSAxLCB3aWR0aCA9IDE5LCBoZWlnaHQgPSAyMCkgKwogICAgZHJhd19wbG90KGdldF9sZWdlbmQoZGlyZWN0aW9uYWxfY2hhbmdlX2xlZ2VuZF9wbG90X2NvbG9yYnl0cmVuZF8xNXBlcmNfZXhjbHUgKyAKICAgICAgdGhlbWUobGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjUsICdjbScpLCAjY2hhbmdlIGxlZ2VuZCBrZXkgc2l6ZQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE2KSwgI2NoYW5nZSBsZWdlbmQgdGl0bGUgZm9udCBzaXplCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNSkpKSwgI2NoYW5nZSBsZWdlbmQgdGV4dCBmb250IHNpemUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IDI3LCB5ID0gOCwgd2lkdGggPSAzLCBoZWlnaHQgPSAyKSArCiAgZ2VvbV90ZXh0KGFlcyh4ID0gMiwgeSA9IDIwLjcpLCBsYWJlbCA9ICgiYS4iKSwgc2l6ZSA9OCwgZm9udGZhY2UgPSAiYm9sZCIpICsKICBnZW9tX3RleHQoYWVzKHggPTIwLCB5ID0gMjAuNyksIGxhYmVsID0gKCJiLiIpLCBzaXplID04LCBmb250ZmFjZSA9ICJib2xkIikKCmdnc2F2ZShCQ190b3RhbF9HQU1fTE1FUl9tZXJnZV9sZWdlbmRfY29sb3JieXRyZW5kXzE1cGVyY19leGNsdSwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAiQkNfdG90YWxfR0FNX0xNRVJfbWVyZ2VfbGVnZW5kX2NvbG9yYnl0cmVuZF8xNXBlcmNfZXhjbHUucG5nIiwgaGVpZ2h0ID0gOCwgd2lkdGggPSAxNCwgdW5pdHMgPSAiaW4iKQpgYGAKCg==